﻿using Link_eLab.SqlSugar.Extension;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Nancy.Json;
using Newtonsoft.Json.Linq;
using OfficeOpenXml;
using OpcUaHelper;
using OpcUaHelper.Model;
using Configuration.ServerApi.Constant;
using Configuration.ServerApi.Dao;
using Configuration.ServerApi.Entity;
using Configuration.ServerApi.Entity.Model;
using Configuration.ServerApi.Enum;
using Configuration.ServerApi.Param;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Configuration.ServerApi.Service.Impl
{
    /// <summary>
    /// ExperimentService
    /// </summary>
    public class ExperimentService : IExperimentService
    {
        #region 公共变量

        JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();

        #endregion

        #region 构造函数

        private readonly IConfiguration Configuration;
        private readonly IHttpContextAccessor Accessor;
        private readonly ISysUserDao SysUserDao;
        private readonly IBisOperationRecordDao BisOperationRecordDao;
        private readonly IBisWarningRecordDao BisWarningRecordDao;
        private readonly IBisDeviceConfigDao BisDeviceConfigDao;
        private readonly IBisExpConfigBalanceDao BisExpConfigBalanceDao;
        private readonly IBisExpConfigBallMillingDao BisExpConfigBallMillingDao;
        private readonly IBisExpConfigBallMillingTwoDao BisExpConfigBallMillingTwoDao;
        private readonly IBisExpConfigBottomFurnaceDao BisExpConfigBottomFurnaceDao;
        private readonly IBisExpConfigCapperDao BisExpConfigCapperDao;
        private readonly IBisExpConfigCapperTwoDao BisExpConfigCapperTwoDao;
        private readonly IBisExpConfigCrucibleConversionDao BisExpConfigCrucibleConversionDao;
        private readonly IBisExpConfigCrusherDao BisExpConfigCrusherDao;
        private readonly IBisExpConfigElectroChemistryTestingDao BisExpConfigElectroChemistryTestingDao;
        private readonly IBisExpConfigFlourBlendingDao BisExpConfigFlourBlendingDao;
        private readonly IBisExpConfigMaterialPositionTableDao BisExpConfigMaterialPositionTableDao;
        private readonly IBisExpConfigNodeDao BisExpConfigNodeDao;
        private readonly IBisExpConfigOvenDao BisExpConfigOvenDao;
        private readonly IBisExpConfigPackagingDao BisExpConfigPackagingDao;
        private readonly IBisExpConfigPipetteDistributionDao BisExpConfigPipetteDistributionDao;
        private readonly IBisExpConfigScrapingDao BisExpConfigScrapingDao;
        private readonly IBisExpConfigSolidLiquidTestingDao BisExpConfigSolidLiquidTestingDao;
        private readonly IBisExpConfigTabletPressDao BisExpConfigTabletPressDao;
        private readonly IBisExpConfigTubeFurnaceDao BisExpConfigTubeFurnaceDao;
        private readonly IBisExpConfigUltrasonicCleaningMachineDao BisExpConfigUltrasonicCleaningMachineDao;
        private readonly IBisExpConfigXRDTestDao BisExpConfigXRDTestDao;
        private readonly IBisExperimentRecordDao BisExperimentRecordDao;
        private readonly IBisExperimentRunLogDao BisExperimentRunLogDao;
        private readonly IBisExperimentRunLogBallMillingDao BisExperimentRunLogBallMillingDao;
        private readonly IBisExperimentRunLogBallMillingTwoDao BisExperimentRunLogBallMillingTwoDao;
        private readonly IBisExperimentRunLogBottomFurnaceDao BisExperimentRunLogBottomFurnaceDao;
        private readonly IBisExperimentRunLogElectroChemistryTestDao BisExperimentRunLogElectroChemistryTestDao;
        private readonly IBisExperimentRunLogOvenDao BisExperimentRunLogOvenDao;
        private readonly IBisExperimentRunLogTubeFurnaceDao BisExperimentRunLogTubeFurnaceDao;
        private readonly IBisExperimentTemplateDao BisExperimentTemplateDao;
        private readonly IBisExperimentTemplateConfigDao BisExperimentTemplateConfigDao;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="accessor"></param>
        /// <param name="sysUserDao"></param>
        /// <param name="bisOperationRecordDao"></param>
        /// <param name="bisWarningRecordDao"></param>
        /// <param name="bisDeviceConfigDao"></param>
        /// <param name="bisExpConfigBalanceDao"></param>
        /// <param name="bisExpConfigBallMillingDao"></param>
        /// <param name="bisExpConfigBallMillingTwoDao"></param>
        /// <param name="bisExpConfigBottomFurnaceDao"></param>
        /// <param name="bisExpConfigCapperDao"></param>
        /// <param name="bisExpConfigCapperTwoDao"></param>
        /// <param name="bisExpConfigCrucibleConversionDao"></param>
        /// <param name="bisExpConfigCrusherDao"></param>
        /// <param name="bisExpConfigElectroChemistryTestingDao"></param>
        /// <param name="bisExpConfigFlourBlendingDao"></param>
        /// <param name="bisExpConfigMaterialPositionTableDao"></param>
        /// <param name="bisExpConfigNodeDao"></param>
        /// <param name="bisExpConfigOvenDao"></param>
        /// <param name="bisExpConfigPackagingDao"></param>
        /// <param name="bisExpConfigPipetteDistributionDao"></param>
        /// <param name="bisExpConfigScrapingDao"></param>
        /// <param name="bisExpConfigSolidLiquidTestingDao"></param>
        /// <param name="bisExpConfigTabletPressDao"></param>
        /// <param name="bisExpConfigTubeFurnaceDao"></param>
        /// <param name="bisExpConfigUltrasonicCleaningMachineDao"></param>
        /// <param name="bisExpConfigXRDTestDao"></param>
        /// <param name="bisExperimentRecordDao"></param>
        /// <param name="bisExperimentRunLogDao"></param>
        /// <param name="bisExperimentRunLogBallMillingDao"></param>
        /// <param name="bisExperimentRunLogBallMillingTwoDao"></param>
        /// <param name="bisExperimentRunLogBottomFurnaceDao"></param>
        /// <param name="bisExperimentRunLogElectroChemistryTestDao"></param>
        /// <param name="bisExperimentRunLogOvenDao"></param>
        /// <param name="bisExperimentRunLogTubeFurnaceDao"></param>
        /// <param name="bisExperimentTemplateDao"></param>
        /// <param name="bisExperimentTemplateConfigDao"></param>
        public ExperimentService(IConfiguration configuration,
            IHttpContextAccessor accessor,
            ISysUserDao sysUserDao,
            IBisOperationRecordDao bisOperationRecordDao,
            IBisWarningRecordDao bisWarningRecordDao,
            IBisDeviceConfigDao bisDeviceConfigDao,
            IBisExpConfigBalanceDao bisExpConfigBalanceDao,
            IBisExpConfigBallMillingDao bisExpConfigBallMillingDao,
            IBisExpConfigBallMillingTwoDao bisExpConfigBallMillingTwoDao,
            IBisExpConfigBottomFurnaceDao bisExpConfigBottomFurnaceDao,
            IBisExpConfigCapperDao bisExpConfigCapperDao,
            IBisExpConfigCapperTwoDao bisExpConfigCapperTwoDao,
            IBisExpConfigCrucibleConversionDao bisExpConfigCrucibleConversionDao,
            IBisExpConfigCrusherDao bisExpConfigCrusherDao,
            IBisExpConfigElectroChemistryTestingDao bisExpConfigElectroChemistryTestingDao,
            IBisExpConfigFlourBlendingDao bisExpConfigFlourBlendingDao,
            IBisExpConfigMaterialPositionTableDao bisExpConfigMaterialPositionTableDao,
            IBisExpConfigNodeDao bisExpConfigNodeDao,
            IBisExpConfigOvenDao bisExpConfigOvenDao,
            IBisExpConfigPackagingDao bisExpConfigPackagingDao,
            IBisExpConfigPipetteDistributionDao bisExpConfigPipetteDistributionDao,
            IBisExpConfigScrapingDao bisExpConfigScrapingDao,
            IBisExpConfigSolidLiquidTestingDao bisExpConfigSolidLiquidTestingDao,
            IBisExpConfigTabletPressDao bisExpConfigTabletPressDao,
            IBisExpConfigTubeFurnaceDao bisExpConfigTubeFurnaceDao,
            IBisExpConfigUltrasonicCleaningMachineDao bisExpConfigUltrasonicCleaningMachineDao,
            IBisExpConfigXRDTestDao bisExpConfigXRDTestDao,
            IBisExperimentRecordDao bisExperimentRecordDao,
            IBisExperimentRunLogDao bisExperimentRunLogDao,
            IBisExperimentRunLogBallMillingDao bisExperimentRunLogBallMillingDao,
            IBisExperimentRunLogBallMillingTwoDao bisExperimentRunLogBallMillingTwoDao,
            IBisExperimentRunLogBottomFurnaceDao bisExperimentRunLogBottomFurnaceDao,
            IBisExperimentRunLogElectroChemistryTestDao bisExperimentRunLogElectroChemistryTestDao,
            IBisExperimentRunLogOvenDao bisExperimentRunLogOvenDao,
            IBisExperimentRunLogTubeFurnaceDao bisExperimentRunLogTubeFurnaceDao,
            IBisExperimentTemplateDao bisExperimentTemplateDao,
            IBisExperimentTemplateConfigDao bisExperimentTemplateConfigDao)
        {
            Configuration = configuration;
            Accessor = accessor;
            SysUserDao = sysUserDao;
            BisOperationRecordDao = bisOperationRecordDao;
            BisWarningRecordDao = bisWarningRecordDao;
            BisDeviceConfigDao = bisDeviceConfigDao;
            BisExpConfigBalanceDao = bisExpConfigBalanceDao;
            BisExpConfigBallMillingDao = bisExpConfigBallMillingDao;
            BisExpConfigBallMillingTwoDao = bisExpConfigBallMillingTwoDao;
            BisExpConfigBottomFurnaceDao = bisExpConfigBottomFurnaceDao;
            BisExpConfigCapperDao = bisExpConfigCapperDao;
            BisExpConfigCapperTwoDao = bisExpConfigCapperTwoDao;
            BisExpConfigCrucibleConversionDao = bisExpConfigCrucibleConversionDao;
            BisExpConfigCrusherDao = bisExpConfigCrusherDao;
            BisExpConfigElectroChemistryTestingDao = bisExpConfigElectroChemistryTestingDao;
            BisExpConfigFlourBlendingDao = bisExpConfigFlourBlendingDao;
            BisExpConfigMaterialPositionTableDao = bisExpConfigMaterialPositionTableDao;
            BisExpConfigNodeDao = bisExpConfigNodeDao;
            BisExpConfigOvenDao = bisExpConfigOvenDao;
            BisExpConfigPackagingDao = bisExpConfigPackagingDao;
            BisExpConfigPipetteDistributionDao = bisExpConfigPipetteDistributionDao;
            BisExpConfigScrapingDao = bisExpConfigScrapingDao;
            BisExpConfigSolidLiquidTestingDao = bisExpConfigSolidLiquidTestingDao;
            BisExpConfigTabletPressDao = bisExpConfigTabletPressDao;
            BisExpConfigTubeFurnaceDao = bisExpConfigTubeFurnaceDao;
            BisExpConfigUltrasonicCleaningMachineDao = bisExpConfigUltrasonicCleaningMachineDao;
            BisExpConfigXRDTestDao = bisExpConfigXRDTestDao;
            BisExperimentRecordDao = bisExperimentRecordDao;
            BisExperimentRunLogDao = bisExperimentRunLogDao;
            BisExperimentRunLogBallMillingDao = bisExperimentRunLogBallMillingDao;
            BisExperimentRunLogBallMillingTwoDao = bisExperimentRunLogBallMillingTwoDao;
            BisExperimentRunLogBottomFurnaceDao = bisExperimentRunLogBottomFurnaceDao;
            BisExperimentRunLogElectroChemistryTestDao = bisExperimentRunLogElectroChemistryTestDao;
            BisExperimentRunLogOvenDao = bisExperimentRunLogOvenDao;
            BisExperimentRunLogTubeFurnaceDao = bisExperimentRunLogTubeFurnaceDao;
            BisExperimentTemplateDao = bisExperimentTemplateDao;
            BisExperimentTemplateConfigDao = bisExperimentTemplateConfigDao;
        }

        #endregion 构造函数

        #region 实验相关方法

        #region 检查实验所需设备是否可用

        /// <summary>
        /// 检查实验所需设备是否可用
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        public ResultModel CheckExpRequiredDeviceStatus(bis_experiment_record ExpRecordData)
        {
            #region 初始化参数

            ResultModel result = new ResultModel();

            #endregion

            // 获取实验关联节点
            List<bis_expconfig_node> ExpNodeData = BisExpConfigNodeDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.Sort).Result;
            if (ExpNodeData == null || ExpNodeData.Count <= 0)
            {
                Console.WriteLine($"{ExpRecordData.Name} ({ExpRecordData.Number}) 实验缺少节点配置信息, 无法运行");

                result.Success = false;
                result.Msg = $"{ExpRecordData.Name} ({ExpRecordData.Number}) 实验缺少节点配置信息, 无法运行";
                return result;
            }

            // 获取控制参数配置
            List<bis_device_config> DeviceConfig = BisDeviceConfigDao.QueryByWhere(w => w.Del_Flag == 0 && w.ParamName.Contains("设备状态")).Result;
            bis_device_config CheckConfig = new bis_device_config();

            // 依次检查每台设备状态
            int Status = 0;
            foreach (var item in ExpNodeData)
            {
                try
                {
                    // 根据节点名称获取对应的设备状态校验命令
                    switch (item.NodeName)
                    {
                        case DeviceName.Capper: { CheckConfig = DeviceConfig.FirstOrDefault(w => "开盖机1工位".Equals(w.Name)); } break;
                        case DeviceName.Capper2: { CheckConfig = DeviceConfig.FirstOrDefault(w => "开盖机2工位".Equals(w.Name)); } break;
                        //case DeviceName.MaterialPositioningTable: {  } break;
                        //case DeviceName.UltrasonicCleaningMachine: { } break;
                        case DeviceName.FlourBlending: { CheckConfig = DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name)); } break;
                        //case DeviceName.PrecisionBalance: { } break;
                        case DeviceName.PipetteDistribution: { CheckConfig = DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name)); } break;
                        case DeviceName.BallMilling: { CheckConfig = DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name)); } break;
                        case DeviceName.BallMilling2: { CheckConfig = DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name)); } break;
                        case DeviceName.Crusher: { CheckConfig = DeviceConfig.FirstOrDefault(w => "破碎机工位".Equals(w.Name)); } break;
                        case DeviceName.Scraping: { CheckConfig = DeviceConfig.FirstOrDefault(w => "刷料机工位".Equals(w.Name)); } break;
                        case DeviceName.Packaging: { CheckConfig = DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name)); } break;
                        case DeviceName.CrucibleConversion: { CheckConfig = DeviceConfig.FirstOrDefault(w => "坩埚转换位".Equals(w.Name)); } break;
                        case DeviceName.TabletPress: { CheckConfig = DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name)); } break;
                        case DeviceName.TubeFurnace: { CheckConfig = DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name)); } break;
                        case DeviceName.BottomFurnace: { CheckConfig = DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name)); } break;
                        case DeviceName.SolidSolidTesting: { CheckConfig = DeviceConfig.FirstOrDefault(w => "固固测试工位".Equals(w.Name)); } break;
                        case DeviceName.SolidLiquidTesting: { CheckConfig = DeviceConfig.FirstOrDefault(w => "固液测试工位".Equals(w.Name)); } break;
                        case DeviceName.ElectroChemistryTesting: { CheckConfig = DeviceConfig.FirstOrDefault(w => "电化学测试工位".Equals(w.Name)); } break;
                        case DeviceName.XRDDevice: { CheckConfig = DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name)); } break;
                        case DeviceName.Oven: { CheckConfig = DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name)); } break;
                    }

                    // 校验当前设备运行状态
                    Status = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckConfig.ParamId)).Value.Value ?? 4;
                    switch (Status)
                    {
                        case 1:
                            {
                                result.Success = true;
                                result.Msg = $"设备校验通过";
                            }
                            break;
                        case 2:
                            {
                                result.Success = false;
                                result.Msg = $"实验所需设备 {item.NodeName} 当前正在运行中, 设备恢复待机状态时会自动进行实验";
                            }
                            break;
                        case 3:
                            {
                                result.Success = false;
                                result.Msg = $"实验所需设备 {item.NodeName} 当前处于故障中, 将设备恢复正常状态时会自动进行实验";
                            }
                            break;
                        case 4:
                            {
                                result.Success = false;
                                result.Msg = $"实验所需设备 {item.NodeName} 当前处于离线中, 将设备恢复正常连接时会自动进行实验";
                            }
                            break;
                    }

                    // 如果本次检测到false时直接返回校验未通过
                    if (!result.Success) { break; }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

            return result;
        }

        #endregion

        #region 初始化运行实验流程

        /// <summary>
        /// 初始化运行实验流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        public async Task<ResultModel> InitExperiment(bis_experiment_record ExpRecordData)
        {
            #region 初始化参数

            Console.WriteLine("初始化实验信息");

            ResultModel result = new ResultModel();
            DateTime now = DateTime.Now;
            List<bis_device_config> TempDeviceConfig = new List<bis_device_config>();

            #endregion

            #region 获取实验相关配置

            Console.WriteLine("获取实验相关配置");

            // 实验关联节点
            List<bis_expconfig_node> ExpNodeData = await BisExpConfigNodeDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.Sort);
            if (ExpNodeData == null || ExpNodeData.Count <= 0)
            {
                Console.WriteLine($"{ExpRecordData.Name} ({ExpRecordData.Number}) 实验缺少节点配置信息, 无法运行");

                result.Success = false;
                result.Msg = $"{ExpRecordData.Name} ({ExpRecordData.Number}) 实验缺少节点配置信息, 无法运行";
                return result;
            }

            // 获取控制参数
            List<bis_device_config> DeviceConfig = await BisDeviceConfigDao.QueryAll();

            #endregion

            #region 进行实验准备工作

            // 切换至自动模式
            ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && "手动0_自动1".Equals(w.ParamName)), true);

            //// 整机实验启动
            //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && "整机实验启动".Equals(w.ParamName)), 1);

            #endregion

            #region 按顺序执行实验步骤

            // 创建运行记录
            CreateExpRunLog(ExpRecordData, $"开始运行实验");
            Thread.Sleep(1000);

            Console.WriteLine("按顺序执行实验步骤");

            ExpNodeData.ForEach(item =>
            {
                // 根据节点名称执行相关的实验流程
                switch (item.NodeName)
                {
                    case DeviceName.Capper: { RunCapper(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.Capper2: { RunCapper2(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.MaterialPositioningTable: { RunMaterialPositioningTable(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.UltrasonicCleaningMachine: { RunUltrasonicCleaningMachine(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.FlourBlending: { RunFlourBlending(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.PrecisionBalance: { RunPrecisionBalance(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.PipetteDistribution: { RunPipetteDistribution(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.BallMilling: { RunBallMilling(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.BallMilling2: { RunBallMilling2(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.Crusher: { RunCrusher(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.Scraping: { RunScraping(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.Packaging: { RunPackaging(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.CrucibleConversion: { RunCrucibleConversion(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.TabletPress: { RunTabletPress(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.TubeFurnace: { RunTubeFurnace(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.BottomFurnace: { RunBottomFurnace(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.SolidSolidTesting: { RunSolidSolidTesting(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.SolidLiquidTesting: { RunSolidLiquidTesting(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.ElectroChemistryTesting: { RunElectroChemistryTesting(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.XRDDevice: { RunXRDTesting(ExpRecordData, DeviceConfig); } break;
                    case DeviceName.Oven: { RunOven(ExpRecordData, DeviceConfig); } break;
                }
            });

            #endregion

            #region 实验执行结束, 更新实验任务状态

            Console.WriteLine("更新实验任务状态");

            // 更新实验任务状态为已完成
            UpdateExpStatus(ExpRecordData.Id, "30");

            // 创建运行记录
            CreateExpRunLog(ExpRecordData, $"实验运行结束");
            Thread.Sleep(1000);

            // 生成实验记录附件
            ExpRecordData = BisExperimentRecordDao.QuerySingle(w => w.Del_Flag == 0 && w.Id.Equals(ExpRecordData.Id)).Result;
            string ExpFilePath = CreateExpLogFile(ExpRecordData);

            // 获取实验创建人详情信息
            var UserData = SysUserDao.QuerySingle(w => w.Del_Flag == 0 && w.Id.Equals(ExpRecordData.CreateUser)).Result;

            // 发送邮件通知
            if (!string.IsNullOrEmpty(UserData.Email))
            {
                EmailHelper.SendEmail(
                    $"实验运行完成通知",
                    $"您创建的 ({ExpRecordData.Number}) {ExpRecordData.Name} 实验运行已完成。",
                    $"{ExpFilePath}",
                    $"{UserData.Email}",
                    $"{Configuration["EmailConfig:FromEmail"]}",
                    $"智能材料科学家系统",
                    $"{Configuration["EmailConfig:FromPassword"]}"
                );
            }

            Console.WriteLine("实验流程执行结束");

            // 调用检查实验任务队列方法以继续执行下个实验
            await CheckExperimentQueue();

            #endregion

            return result;
        }

        #endregion

        #region 发送控制命令

        /// <summary>
        /// 发送控制命令
        /// </summary>
        /// <param name="Config">配置信息</param>
        /// <param name="SetValue">自定义写入值</param>
        /// <returns>成功或失败</returns>
        public bool ExecuteCmd(bis_device_config Config, object SetValue = null)
        {
            try
            {
                var result = Global.KepServer.Write(Config.ParamId, SetValue ?? Config.DefaultValue);
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return false;
            }
        }

        /// <summary>
        /// 发送控制命令
        /// </summary>
        /// <param name="Id">参数ID</param>
        /// <param name="Value">参数值</param>
        /// <returns>成功或失败</returns>
        public bool ExecuteCmd(string Id, object Value)
        {
            try
            {
                return Global.KepServer.Write(Id, Value);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return false;
            }
        }

        #endregion

        #region 更新实验任务状态

        /// <summary>
        /// 更新实验任务状态
        /// </summary>
        /// <param name="ExpId">实验ID</param>
        /// <param name="Status">实验任务状态  10: 队列中 20: 进行中 30: 已完成 40: 已终止 50: 已取消</param>
        public void UpdateExpStatus(string ExpId, string Status)
        {
            int result = 0;

            switch (Status)
            {
                case "10":
                    {

                    }
                    break;
                case "20":
                    {
                        result = BisExperimentRecordDao.Update(u => new bis_experiment_record()
                        {
                            Status = Status,
                            ExpStartTime = DateTime.Now
                        }, w => w.Id.Equals(ExpId)).Result;
                    }
                    break;
                case "30":
                case "40":
                case "50":
                    {
                        result = BisExperimentRecordDao.Update(u => new bis_experiment_record()
                        {
                            Status = Status,
                            ExpEndTime = DateTime.Now
                        }, w => w.Id.Equals(ExpId)).Result;
                    }
                    break;
            }
        }

        #endregion

        #region 检测设备是否存在报警状态

        /// <summary>
        /// 是否检测设备报警状态
        /// </summary>
        private bool IsCheckDevice { get; set; } = false;

        /// <summary>
        /// 检测设备是否存在报警状态
        /// </summary>
        /// <param name="DeviceConfig">控制命令</param>
        /// <param name="Name">设备名称</param>
        /// <param name="WaitingTime">单次检测等待时长 (秒)</param>
        public void CheckDeviceWarning(List<bis_device_config> DeviceConfig, string Name, int WaitingTime = 10)
        {
            #region 初始化参数

            // 检测命令
            bis_device_config CheckCmd = new bis_device_config();

            // 检测返回结果
            ValueModel CheckResult = new ValueModel();

            #endregion

            Task.Run(() =>
            {
                // 标识为开始检测状态
                IsCheckDevice = true;

                do
                {
                    try
                    {
                        switch (Name)
                        {
                            case DeviceName.AutoGuideVehicle:                  // AGV小车
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.AutoGuideVehicle, $"系统检测到 {DeviceName.AutoGuideVehicle} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Capper:                                   // 反应釜开盖机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Capper, $"系统检测到 {DeviceName.Capper} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Capper2:                                 // 试管开盖机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Capper2, $"系统检测到 {DeviceName.Capper2} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.MaterialPositioningTable:        // 物料定位台
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.MaterialPositioningTable, $"系统检测到 {DeviceName.MaterialPositioningTable} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.PrecisionBalance:                    // 精密天平
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.PrecisionBalance, $"系统检测到 {DeviceName.PrecisionBalance} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.FlourBlending:                         // 高通量配粉系统
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.FlourBlending, $"系统检测到 {DeviceName.FlourBlending} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.PipetteDistribution:                  // 移液配比系统
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.PipetteDistribution, $"系统检测到 {DeviceName.PipetteDistribution} 处于 故障中 状态，请及时检查设备运行情况");
                                    }

                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "1000ul枪头用完".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TubeFurnace, $"系统检测到 {DeviceName.TubeFurnace} 的 1000ul枪头 已用完，请及时检查设备运行情况");
                                    }

                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "5000ul枪头用完".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TubeFurnace, $"系统检测到 {DeviceName.TubeFurnace} 的 5000ul枪头 已用完，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.BallMilling:                              // 球磨机1
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.BallMilling, $"系统检测到 {DeviceName.BallMilling} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.BallMilling2:                            // 球磨机2
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.BallMilling2, $"系统检测到 {DeviceName.BallMilling2} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Crusher:                                  // 颚式破碎机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Crusher, $"系统检测到 {DeviceName.Crusher} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Scraping:                                 // 刷料机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Scraping, $"系统检测到 {DeviceName.Scraping} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.CrucibleConversion:                // 坩埚转换位
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.CrucibleConversion, $"系统检测到 {DeviceName.CrucibleConversion} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Packaging:                              // 自动化电池封装机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Packaging, $"系统检测到 {DeviceName.Packaging} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.TabletPress:                            // 陶瓷压片机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TabletPress, $"系统检测到 {DeviceName.TabletPress} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.TubeFurnace:                          // 管式炉
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TubeFurnace, $"系统检测到 {DeviceName.TubeFurnace} 处于 故障中 状态，请及时检查设备运行情况");
                                    }

                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "超温报警状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TubeFurnace, $"系统检测到 {DeviceName.TubeFurnace} 处于 超温报警状态 状态，请及时检查设备运行情况");
                                    }

                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "压力报警状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.TubeFurnace, $"系统检测到 {DeviceName.TubeFurnace} 处于 压力报警状态 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.BottomFurnace:                      // 下装炉
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.BottomFurnace, $"系统检测到 {DeviceName.BottomFurnace} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.SolidSolidTesting:                   // 固固测试平台
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.SolidSolidTesting, $"系统检测到 {DeviceName.SolidSolidTesting} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.SolidLiquidTesting:                 // 固液测试平台
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.SolidLiquidTesting, $"系统检测到 {DeviceName.SolidLiquidTesting} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.ElectroChemistryTesting:        // 电化学测试仪器
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.ElectroChemistryTesting, $"系统检测到 {DeviceName.ElectroChemistryTesting} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.XRDDevice:                            // XRD测试仪
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.XRDDevice, $"系统检测到 {DeviceName.XRDDevice} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                            case DeviceName.Oven:                                   // 自动化烘干机
                                {
                                    // 发送命令并返回结果
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;

                                    // 如果返回值不为空 并且 设备状态为故障中时
                                    if (CheckResult.Value != null && int.Parse(CheckResult.Value) == 3)
                                    {
                                        CreateWarningRecord(DeviceName.Oven, $"系统检测到 {DeviceName.Oven} 处于 故障中 状态，请及时检查设备运行情况");
                                    }
                                }
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }

                    // 等待后进入下次检测
                    Thread.Sleep(WaitingTime * 1000);

                } while (IsCheckDevice == true);
            });
        }

        #endregion

        #region 生成实验关联数据相关方法

        #region 创建实验运行记录

        /// <summary>
        /// 创建实验运行记录
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="Content">内容</param>
        /// <param name="Title">标题</param>
        public void CreateExpRunLog(bis_experiment_record ExpRecordData, string Content, string Title = "运行记录")
        {
            DateTime now = DateTime.Now;
            _ = BisExperimentRunLogDao.Insert(new bis_experiment_runlog()
            {
                Id = Guid.NewGuid().ToString().ToUpper(),
                ExpId = ExpRecordData.Id,
                ExpName = ExpRecordData.Name,
                Title = Title,
                Content = Content,
                CreateUser = "",
                CreateUserName = "系统",
                CreateTime = now,
                Del_Flag = 0
            }).Result;
        }

        #endregion

        #region 创建报警记录

        /// <summary>
        /// 创建报警记录
        /// </summary>
        /// <param name="Title">预警标题 (预警设备名称)</param>
        /// <param name="Content">预警内容</param>
        /// <param name="Type">预警类型  10: 设备预警</param>
        public void CreateWarningRecord(string Title, string Content, string Type = "10")
        {
            DateTime now = DateTime.Now;
            _ = BisWarningRecordDao.Insert(new bis_warning_record()
            {
                Id = Guid.NewGuid().ToString().ToUpper(),
                Type = Type,
                Title = Title,
                Content = Content,
                OrgGuid = "",
                OrgName = "",
                CreateUser = "",
                CreateUserName = "系统",
                CreateTime = now,
                UpdateUser = "",
                UpdateUserName = "系统",
                UpdateTime = now,
                Del_Flag = 0
            }).Result;
        }

        #endregion

        #region 创建设备实时状态记录数据

        /// <summary>
        /// 是否实时记录实验数据
        /// </summary>
        private bool IsRecordedData { get; set; } = false;

        /// <summary>
        /// 创建设备实时状态记录数据
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        /// <param name="Name">设备名称</param>
        /// <param name="WaitingTime">单次检测等待时长 (秒)</param>
        public void CreateDeviceExpRecord(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig, string Name, int WaitingTime = 1)
        {
            #region 初始化参数

            // 检测命令
            bis_device_config CheckCmd = new bis_device_config();

            // 检测返回结果
            ValueModel CheckResult = new ValueModel();

            #endregion

            Task.Run(() =>
            {
                // 标识为开始检测状态
                IsRecordedData = true;

                Console.WriteLine($"开始记录{Name}工位设备实时状态数据");
                do
                {
                    try
                    {
                        switch (Name)
                        {
                            // 球磨机1：采集实际速度，并绘制时间-速度曲线；
                            case DeviceName.BallMilling:
                                {
                                    #region 获取相关数据

                                    // 当前速度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "当前速度".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    int Speed = CheckResult.Value == null ? int.Parse(CheckResult.Value) : 0;

                                    #endregion

                                    // 新增数据
                                    _ = BisExperimentRunLogBallMillingDao.Insert(new bis_experiment_runlog_ballmilling()
                                    {
                                        Id = Guid.NewGuid().ToString().ToUpper(),
                                        ExpId = ExpRecordData.Id,
                                        ExpName = ExpRecordData.Name,
                                        Speed = Speed,
                                        CreateTime = DateTime.Now,
                                        Del_Flag = 0
                                    }).Result;
                                }
                                break;
                            // 球磨机2：采集实际速度，并绘制时间-速度曲线；
                            case DeviceName.BallMilling2:
                                {
                                    #region 获取相关数据

                                    // 当前速度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "当前速度".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    int Speed = CheckResult.Value == null ? int.Parse(CheckResult.Value) : 0;

                                    #endregion

                                    // 新增数据
                                    _ = BisExperimentRunLogBallMillingTwoDao.Insert(new bis_experiment_runlog_ballmilling_two()
                                    {
                                        Id = Guid.NewGuid().ToString().ToUpper(),
                                        ExpId = ExpRecordData.Id,
                                        ExpName = ExpRecordData.Name,
                                        Speed = Speed,
                                        CreateTime = DateTime.Now,
                                        Del_Flag = 0
                                    }).Result;
                                }
                                break;
                            // 管式炉：记录实际温度值、实际进气流量值、真空压力值，并绘制曲线；
                            case DeviceName.TubeFurnace:
                                {
                                    #region 获取相关数据

                                    // 实际温度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温度PV".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal RealityTemp = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    // 实际进气流量
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "进气流量PV".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal RealityIntakeFlowRate = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    // 真空压力值
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "真空压力值".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal VacuumPressureValue = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    #endregion

                                    // 新增数据
                                    _ = BisExperimentRunLogTubeFurnaceDao.Insert(new bis_experiment_runlog_tubefurnace()
                                    {
                                        Id = Guid.NewGuid().ToString().ToUpper(),
                                        ExpId = ExpRecordData.Id,
                                        ExpName = ExpRecordData.Name,
                                        RealityTemp = RealityTemp,
                                        RealityIntakeFlowRate = RealityIntakeFlowRate,
                                        VacuumPressureValue = VacuumPressureValue,
                                        CreateTime = DateTime.Now,
                                        Del_Flag = 0
                                    }).Result;
                                }
                                break;
                            // 下装炉：记录实际温度值，并绘制时间-温度曲线，曲线图需同时有设定温度和实际温度曲线；
                            case DeviceName.BottomFurnace:
                                {
                                    #region 获取相关数据

                                    // 设定温度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温度SV".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal SettingTemp = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    // 实际温度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温度PV".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal RealityTemp = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    #endregion

                                    // 新增数据
                                    _ = BisExperimentRunLogBottomFurnaceDao.Insert(new bis_experiment_runlog_bottomfurnace()
                                    {
                                        Id = Guid.NewGuid().ToString().ToUpper(),
                                        ExpId = ExpRecordData.Id,
                                        ExpName = ExpRecordData.Name,
                                        SettingTemp = SettingTemp,
                                        RealityTemp = RealityTemp,
                                        CreateTime = DateTime.Now,
                                        Del_Flag = 0
                                    }).Result;
                                }
                                break;
                            // 自动化烘干机：记录测量温度和测量转速，并绘制相应的时间-参数曲线；
                            case DeviceName.Oven:
                                {
                                    #region 获取相关数据

                                    // 测量温度
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "测量温度".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    decimal MeasureTemp = CheckResult.Value == null ? decimal.Parse(CheckResult.Value) : 0;

                                    // 测量转速
                                    CheckCmd = DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "测量转速".Equals(w.ParamName));
                                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                                    int MeasureSpeed = CheckResult.Value == null ? int.Parse(CheckResult.Value) : 0;

                                    #endregion

                                    // 新增数据
                                    _ = BisExperimentRunLogOvenDao.Insert(new bis_experiment_runlog_oven()
                                    {
                                        Id = Guid.NewGuid().ToString().ToUpper(),
                                        ExpId = ExpRecordData.Id,
                                        ExpName = ExpRecordData.Name,
                                        MeasureTemp = MeasureTemp,
                                        MeasureSpeed = MeasureSpeed,
                                        CreateTime = DateTime.Now,
                                        Del_Flag = 0
                                    }).Result;
                                }
                                break;
                            // 其他设备无需记录实验数据, 直接终止记录
                            default:
                                {
                                    Console.WriteLine($"此工位暂无可以记录的实时状态数据");

                                    // 停止记录实验数据
                                    IsRecordedData = false;
                                }
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }

                    // 等待后进入下次检测
                    Thread.Sleep(WaitingTime * 1000);

                } while (IsRecordedData == true);
            });
        }

        #endregion

        #region 生成实验数据记录文件

        /// <summary>
        /// 生成实验数据记录文件
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <returns>生成文件地址</returns>
        public string CreateExpLogFile(bis_experiment_record ExpRecordData)
        {
            try
            {
                #region 生成Excel文件

                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                ExcelPackage package = new ExcelPackage();

                #region 生成基本信息数据

                // 新建表格Sheet页
                var WorkSheet_BasicInfo = package.Workbook.Worksheets.Add("实验基本信息");

                // 填充数据
                WorkSheet_BasicInfo.Cells[1, 1].Value = $"实验任务名称：{ExpRecordData.Name}";
                WorkSheet_BasicInfo.Cells[2, 1].Value = $"实验任务编号：{ExpRecordData.Number}";
                WorkSheet_BasicInfo.Cells[3, 1].Value = $"实验开始时间：{ExpRecordData.ExpStartTime.Value:yyyy-MM-dd HH:mm:ss}";
                WorkSheet_BasicInfo.Cells[4, 1].Value = $"实验结束时间：{ExpRecordData.ExpEndTime.Value:yyyy-MM-dd HH:mm:ss}";
                WorkSheet_BasicInfo.Cells[5, 1].Value = $"创建人：{ExpRecordData.CreateUserName}";
                WorkSheet_BasicInfo.Cells[6, 1].Value = $"创建时间：{ExpRecordData.CreateTime.Value:yyyy-MM-dd HH:mm:ss}";

                // 调整列宽
                WorkSheet_BasicInfo.Column(1).Width = 50.00;

                #endregion

                #region 生成运行日志数据

                // 获取实验运行日志数据
                var ExpRunLogData = BisExperimentRunLogDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Desc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLog = package.Workbook.Worksheets.Add("实验运行日志");

                // 初始化内容
                WorkSheet_ExpRunLog.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLog.Cells[1, 1].Value = "创建时间";                     // 第一行第一列标题
                WorkSheet_ExpRunLog.Cells[1, 2].Value = "内容";                           // 第一行第二列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogData.Count; i++)
                {
                    // 创建时间
                    WorkSheet_ExpRunLog.Cells[i + 2, 1].Value = $"{ExpRunLogData[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";

                    // 内容
                    WorkSheet_ExpRunLog.Cells[i + 2, 2].Value = ExpRunLogData[i].Content;
                }

                // 调整列宽
                WorkSheet_ExpRunLog.Column(1).Width = 25.00;
                WorkSheet_ExpRunLog.Column(2).Width = 150.00;

                #endregion

                #region 生成球磨机1设备运行数据

                // 获取实验运行日志数据
                var ExpRunLogDataBallMilling = BisExperimentRunLogBallMillingDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Asc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLogBallMilling = package.Workbook.Worksheets.Add("实验数据-球磨机1");

                // 初始化内容
                WorkSheet_ExpRunLogBallMilling.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLogBallMilling.Cells[1, 1].Value = "实际速度";                     // 第一行第一列标题
                WorkSheet_ExpRunLogBallMilling.Cells[1, 2].Value = "创建时间";                     // 第一行第二列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogDataBallMilling.Count; i++)
                {
                    // 实际速度
                    WorkSheet_ExpRunLogBallMilling.Cells[i + 2, 1].Value = ExpRunLogDataBallMilling[i].Speed;

                    // 创建时间
                    WorkSheet_ExpRunLogBallMilling.Cells[i + 2, 2].Value = $"{ExpRunLogDataBallMilling[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";
                }

                // 调整列宽
                WorkSheet_ExpRunLogBallMilling.Column(1).Width = 25.00;
                WorkSheet_ExpRunLogBallMilling.Column(2).Width = 25.00;

                #endregion

                #region 生成球磨机2设备运行数据

                // 获取实验运行日志数据
                var ExpRunLogDataBallMillingTwo = BisExperimentRunLogBallMillingTwoDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Asc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLogBallMillingTwo = package.Workbook.Worksheets.Add("实验数据-球磨机2");

                // 初始化内容
                WorkSheet_ExpRunLogBallMillingTwo.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLogBallMillingTwo.Cells[1, 1].Value = "实际速度";                     // 第一行第一列标题
                WorkSheet_ExpRunLogBallMillingTwo.Cells[1, 2].Value = "创建时间";                     // 第一行第二列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogDataBallMillingTwo.Count; i++)
                {
                    // 实际速度
                    WorkSheet_ExpRunLogBallMillingTwo.Cells[i + 2, 1].Value = ExpRunLogDataBallMillingTwo[i].Speed;

                    // 创建时间
                    WorkSheet_ExpRunLogBallMillingTwo.Cells[i + 2, 2].Value = $"{ExpRunLogDataBallMillingTwo[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";
                }

                // 调整列宽
                WorkSheet_ExpRunLogBallMillingTwo.Column(1).Width = 25.00;
                WorkSheet_ExpRunLogBallMillingTwo.Column(2).Width = 25.00;

                #endregion

                #region 生成管式炉设备运行数据

                // 获取实验运行日志数据
                var ExpRunLogDataTubeFurnace = BisExperimentRunLogTubeFurnaceDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Asc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLogTubeFurnace = package.Workbook.Worksheets.Add("实验数据-管式炉");

                // 初始化内容
                WorkSheet_ExpRunLogTubeFurnace.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLogTubeFurnace.Cells[1, 1].Value = "实际温度";                     // 第一行第一列标题
                WorkSheet_ExpRunLogTubeFurnace.Cells[1, 2].Value = "实际进气流量";               // 第一行第二列标题
                WorkSheet_ExpRunLogTubeFurnace.Cells[1, 3].Value = "真空压力值";                  // 第一行第三列标题
                WorkSheet_ExpRunLogTubeFurnace.Cells[1, 4].Value = "创建时间";                     // 第一行第四列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogDataTubeFurnace.Count; i++)
                {
                    // 实际温度
                    WorkSheet_ExpRunLogTubeFurnace.Cells[i + 2, 1].Value = ExpRunLogDataTubeFurnace[i].RealityTemp;

                    // 实际进气流量
                    WorkSheet_ExpRunLogTubeFurnace.Cells[i + 2, 2].Value = ExpRunLogDataTubeFurnace[i].RealityIntakeFlowRate;

                    // 真空压力值
                    WorkSheet_ExpRunLogTubeFurnace.Cells[i + 2, 3].Value = ExpRunLogDataTubeFurnace[i].VacuumPressureValue;

                    // 创建时间
                    WorkSheet_ExpRunLogTubeFurnace.Cells[i + 2, 4].Value = $"{ExpRunLogDataTubeFurnace[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";
                }

                // 调整列宽
                WorkSheet_ExpRunLogTubeFurnace.Column(1).Width = 25.00;
                WorkSheet_ExpRunLogTubeFurnace.Column(2).Width = 25.00;
                WorkSheet_ExpRunLogTubeFurnace.Column(3).Width = 25.00;
                WorkSheet_ExpRunLogTubeFurnace.Column(4).Width = 25.00;

                #endregion

                #region 生成下装炉设备运行数据

                // 获取实验运行日志数据
                var ExpRunLogDataBottomFurnace = BisExperimentRunLogBottomFurnaceDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Asc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLogBottomFurnace = package.Workbook.Worksheets.Add("实验数据-下装炉");

                // 初始化内容
                WorkSheet_ExpRunLogBottomFurnace.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLogBottomFurnace.Cells[1, 1].Value = "设定温度";                     // 第一行第一列标题
                WorkSheet_ExpRunLogBottomFurnace.Cells[1, 2].Value = "实际温度";                     // 第一行第二列标题
                WorkSheet_ExpRunLogBottomFurnace.Cells[1, 3].Value = "测量转速";                     // 第一行第三列标题
                WorkSheet_ExpRunLogBottomFurnace.Cells[1, 4].Value = "创建时间";                     // 第一行第四列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogDataBottomFurnace.Count; i++)
                {
                    // 设定温度
                    WorkSheet_ExpRunLogBottomFurnace.Cells[i + 2, 1].Value = ExpRunLogDataBottomFurnace[i].SettingTemp;

                    // 实际温度
                    WorkSheet_ExpRunLogBottomFurnace.Cells[i + 2, 2].Value = ExpRunLogDataBottomFurnace[i].RealityTemp;

                    // 测量转速
                    WorkSheet_ExpRunLogBottomFurnace.Cells[i + 2, 3].Value = ExpRunLogDataBottomFurnace[i].MeasureSpeed;

                    // 创建时间
                    WorkSheet_ExpRunLogBottomFurnace.Cells[i + 2, 4].Value = $"{ExpRunLogDataBottomFurnace[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";
                }

                // 调整列宽
                WorkSheet_ExpRunLogBottomFurnace.Column(1).Width = 25.00;
                WorkSheet_ExpRunLogBottomFurnace.Column(2).Width = 25.00;
                WorkSheet_ExpRunLogBottomFurnace.Column(3).Width = 25.00;
                WorkSheet_ExpRunLogBottomFurnace.Column(4).Width = 25.00;

                #endregion

                #region 生成自动化烘干机设备运行数据

                // 获取实验运行日志数据
                var ExpRunLogDataOven = BisExperimentRunLogOvenDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id), o => o.CreateTime, OrderByType.Asc).Result;

                // 新建表格Sheet页
                var WorkSheet_ExpRunLogOven = package.Workbook.Worksheets.Add("实验数据-烘箱");

                // 初始化内容
                WorkSheet_ExpRunLogOven.Columns.AutoFit();                                      // 设置自动列宽

                // 录入识别结果信息
                WorkSheet_ExpRunLogOven.Cells[1, 1].Value = "测量温度";                     // 第一行第一列标题
                WorkSheet_ExpRunLogOven.Cells[1, 2].Value = "测量转速";                     // 第一行第二列标题
                WorkSheet_ExpRunLogOven.Cells[1, 3].Value = "创建时间";                     // 第一行第三列标题

                // 填充数据
                for (var i = 0; i < ExpRunLogDataOven.Count; i++)
                {
                    // 测量温度
                    WorkSheet_ExpRunLogOven.Cells[i + 2, 1].Value = ExpRunLogDataOven[i].MeasureTemp;

                    // 测量转速
                    WorkSheet_ExpRunLogOven.Cells[i + 2, 2].Value = ExpRunLogDataOven[i].MeasureSpeed;

                    // 创建时间
                    WorkSheet_ExpRunLogOven.Cells[i + 2, 3].Value = $"{ExpRunLogDataOven[i].CreateTime.Value:yyyy-MM-dd HH:mm:ss}";
                }

                // 调整列宽
                WorkSheet_ExpRunLogOven.Column(1).Width = 25.00;
                WorkSheet_ExpRunLogOven.Column(2).Width = 25.00;
                WorkSheet_ExpRunLogOven.Column(3).Width = 25.00;

                #endregion

                // 将数据存储至临时MemoryStream
                var fs = new MemoryStream();
                package.SaveAsAsync(fs);

                #endregion

                // 初始化文件保存位置
                string FilePath = $"{AppDomain.CurrentDomain.BaseDirectory}ExperimentResult";
                if (!Directory.Exists(FilePath)) { Directory.CreateDirectory(FilePath); }
                FilePath += $"\\[{ExpRecordData.Name}({ExpRecordData.Number})]-实验运行记录.xlsx";

                // 写入文件
                using FileStream file = new FileStream($"{FilePath}", FileMode.Create, FileAccess.Write);
                file.Write(fs.ToArray(), 0, (int)fs.Length);

                return FilePath;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return "";
            }
        }

        #endregion

        #endregion

        #region 运行实验流程相关方法

        #region 移动AGV小车至指定位置

        /// <summary>
        /// 移动AGV小车至指定位置
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        /// <param name="DeviceStationName">设备名称</param>
        /// <param name="DeviceStationNumber">设备位置号</param>
        public void MoveAgvVehicle(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig, string DeviceStationName, int DeviceStationNumber)
        {
            Console.WriteLine($"开始运行{DeviceName.AutoGuideVehicle}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始移动{DeviceName.AutoGuideVehicle}至{DeviceStationName}工位");

                // 发送启动命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "设定位置号".Equals(w.ParamName)), DeviceStationNumber);
                Thread.Sleep(3000);

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.AutoGuideVehicle);

                // 开始记录实验数据
                CreateDeviceExpRecord(ExpRecordData, DeviceConfig, DeviceStationName);

                // 检测是否正在进行实验命令
                bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设定位置号".Equals(w.ParamName));
                //bis_device_config CheckCmd2 = DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && "Standby2".Equals(w.ParamName));

                // 检测返回结果
                ValueModel CheckResult = new ValueModel();
                //ValueModel CheckResult2 = new ValueModel();

                bool IsExecuting = true;
                do
                {
                    // 获取结果
                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                    //CheckResult2 = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd2.ParamId)).Value;
                    if (CheckResult.Value == null)
                    {
                        // 标记为已结束状态
                        IsExecuting = false;
                    }
                    else
                    {
                        // 如果 位置号为0 并且 机器人在待机位 时
                        //if (int.Parse(CheckResult.Value) == 0 && CheckResult2.Value == true)
                        if (int.Parse(CheckResult.Value) == 0)
                        {
                            // 标记为已结束状态
                            IsExecuting = false;
                        }
                    }

                    // 等待1秒，继续判断
                    Thread.Sleep(1000);

                } while (IsExecuting == true);

                // 跳出循序时表示执行结束，进入实验终止阶段

                // 停止记录实验数据
                IsRecordedData = false;

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"已完成移动{DeviceName.AutoGuideVehicle}至{DeviceStationName}工位");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.AutoGuideVehicle}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 检查设备是否处于待机中

        /// <summary>
        /// 检查设备是否处于待机中
        /// </summary>
        /// <param name="DeviceConfig">控制命令</param>
        /// <param name="DeviceStationName">设备名称</param>
        public void CheckDeviceIsStandby(List<bis_device_config> DeviceConfig, string DeviceStationName)
        {
            try
            {
                // 检测是否正在进行实验命令
                bis_device_config CheckCmd = new bis_device_config();

                // 根据节点名称获取对应的设备状态校验命令
                switch (DeviceStationName)
                {
                    case DeviceName.Capper: { CheckCmd = DeviceConfig.FirstOrDefault(w => "开盖机1工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.Capper2: { CheckCmd = DeviceConfig.FirstOrDefault(w => "开盖机2工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    //case DeviceName.MaterialPositioningTable: {  } break;
                    //case DeviceName.UltrasonicCleaningMachine: { } break;
                    case DeviceName.FlourBlending: { CheckCmd = DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    //case DeviceName.PrecisionBalance: { } break;
                    case DeviceName.PipetteDistribution: { CheckCmd = DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.BallMilling: { CheckCmd = DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.BallMilling2: { CheckCmd = DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.Crusher: { CheckCmd = DeviceConfig.FirstOrDefault(w => "破碎机工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.Scraping: { CheckCmd = DeviceConfig.FirstOrDefault(w => "刷料机工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.Packaging: { CheckCmd = DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.CrucibleConversion: { CheckCmd = DeviceConfig.FirstOrDefault(w => "坩埚转换位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.TabletPress: { CheckCmd = DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.TubeFurnace: { CheckCmd = DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.BottomFurnace: { CheckCmd = DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.SolidSolidTesting: { CheckCmd = DeviceConfig.FirstOrDefault(w => "固固测试工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.SolidLiquidTesting: { CheckCmd = DeviceConfig.FirstOrDefault(w => "固液测试工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.ElectroChemistryTesting: { CheckCmd = DeviceConfig.FirstOrDefault(w => "电化学测试工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.XRDDevice: { CheckCmd = DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                    case DeviceName.Oven: { CheckCmd = DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设备状态".Equals(w.ParamName)); } break;
                }

                // 检测返回结果
                ValueModel CheckResult = new ValueModel();

                bool IsExecuting = true;
                do
                {
                    // 获取结果
                    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                    if (CheckResult.Value == null)
                    {
                        // 标记为已结束状态
                        IsExecuting = false;
                    }
                    else
                    {
                        // 如果设备状态为空闲时
                        if (int.Parse(CheckResult.Value) == 1)
                        {
                            // 标记为已结束状态
                            IsExecuting = false;
                        }
                    }

                    // 等待1秒，继续判断
                    Thread.Sleep(1000);

                } while (IsExecuting == true);

                // 跳出循序时表示设备处于待机中, 等待片刻后进行返回
                Thread.Sleep(1000 * 20);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        #endregion

        #region 运行反应釜开盖机工位设备流程

        /// <summary>
        /// 运行反应釜开盖机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunCapper(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Capper}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Capper}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Capper)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigCapperDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机2工位".Equals(w.Name) && "复位开盖机".Equals(w.ParamName)), true);
                    switch (ConfigData.Operate)
                    {
                        // 开盖
                        case 0:
                            {
                                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机2工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), 2);
                            }
                            break;
                        // 锁盖
                        case 1:
                            {
                                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机2工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), 1);
                            }
                            break;
                    }
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动开盖流程启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Capper);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Capper);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Capper, DeviceStationNumber.GetNumber(DeviceName.Capper));

                //// 检查设备是否处于待机中
                //CheckDeviceIsStandby(DeviceConfig, DeviceName.Capper);

                // 执行完成, 等待片刻后进行返回
                Thread.Sleep(1000 * 20);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Capper}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Capper}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行试管开盖机工位设备流程

        /// <summary>
        /// 运行试管开盖机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunCapper2(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Capper2}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Capper2}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Capper2)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigCapperTwoDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机1工位".Equals(w.Name) && "复位开盖机".Equals(w.ParamName)), true);
                    switch (ConfigData.Operate)
                    {
                        // 开盖
                        case 0:
                            {
                                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机1工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), 2);
                            }
                            break;
                        // 锁盖
                        case 1:
                            {
                                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开盖机1工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), 1);
                            }
                            break;
                    }
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动开盖流程启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Capper);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Capper2);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Capper2, DeviceStationNumber.GetNumber(DeviceName.Capper2));

                //// 检查设备是否处于待机中
                //CheckDeviceIsStandby(DeviceConfig, DeviceName.Capper2);

                // 执行完成, 等待片刻后进行返回
                Thread.Sleep(1000 * 20);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Capper2}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Capper2}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行物料定位台工位设备流程

        /// <summary>
        /// 运行物料定位台工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunMaterialPositioningTable(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.MaterialPositioningTable}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.MaterialPositioningTable}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.MaterialPositioningTable)}]".Equals(w.ParamName)), true);

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.MaterialPositioningTable);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.MaterialPositioningTable, DeviceStationNumber.GetNumber(DeviceName.MaterialPositioningTable));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.MaterialPositioningTable);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.MaterialPositioningTable}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.MaterialPositioningTable}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行超声波清洗机工位设备流程

        /// <summary>
        /// 运行超声波清洗机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunUltrasonicCleaningMachine(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.UltrasonicCleaningMachine}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.UltrasonicCleaningMachine}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.UltrasonicCleaningMachine)}]".Equals(w.ParamName)), true);

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.UltrasonicCleaningMachine);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.UltrasonicCleaningMachine, DeviceStationNumber.GetNumber(DeviceName.UltrasonicCleaningMachine));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.UltrasonicCleaningMachine);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.UltrasonicCleaningMachine}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.UltrasonicCleaningMachine}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行精密天平工位设备流程

        /// <summary>
        /// 运行精密天平工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunPrecisionBalance(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.PrecisionBalance}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.PrecisionBalance}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.PrecisionBalance)}]".Equals(w.ParamName)), true);

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.PrecisionBalance);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.PrecisionBalance, DeviceStationNumber.GetNumber(DeviceName.PrecisionBalance));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.PrecisionBalance);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.PrecisionBalance}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.PrecisionBalance}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行高通量配粉系统工位设备流程

        /// <summary>
        /// 运行高通量配粉系统工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunFlourBlending(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.FlourBlending}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.FlourBlending}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.FlourBlending)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigFlourBlendingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "1料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup1_Tank5_Weight);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "2料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup2_Tank5_Weight);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "3料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup3_Tank5_Weight);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "4料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup4_Tank5_Weight);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "5料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup5_Tank5_Weight);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6号料杯启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯1料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank1_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯1料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank1_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯2料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank2_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯2料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank2_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯3料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank3_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯3料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank3_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯4料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank4_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯4料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank4_Weight);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯5料罐启用".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank5_Status == true ? 0 : 1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "6料杯5料罐设定重量".Equals(w.ParamName)), ConfigData.MaterialCup6_Tank5_Weight);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "高通量配粉工位".Equals(w.Name) && "下载参数启动".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "上位机进仓控制启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.FlourBlending);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.FlourBlending);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.FlourBlending, DeviceStationNumber.GetNumber(DeviceName.FlourBlending));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.FlourBlending);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.FlourBlending}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.FlourBlending}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行移液配比系统工位设备流程

        /// <summary>
        /// 运行移液配比系统工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunPipetteDistribution(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.PipetteDistribution}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.PipetteDistribution}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.PipetteDistribution)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigPipetteDistributionDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    if (ConfigData.Crucible1_Status)
                    {
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "坩埚位置设定".Equals(w.ParamName)), 1);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "1坩埚A溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible1_Aspiration_Weight_A);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "1坩埚B溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible1_Aspiration_Weight_B);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "1坩埚C溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible1_Aspiration_Weight_C);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "1坩埚D溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible1_Aspiration_Weight_D);
                    }

                    if (ConfigData.Crucible2_Status)
                    {
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "坩埚位置设定".Equals(w.ParamName)), 2);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "2坩埚A溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible2_Aspiration_Weight_A);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "2坩埚B溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible2_Aspiration_Weight_B);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "2坩埚C溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible2_Aspiration_Weight_C);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "2坩埚D溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible2_Aspiration_Weight_D);
                    }

                    if (ConfigData.Crucible3_Status)
                    {
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "坩埚位置设定".Equals(w.ParamName)), 3);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "3坩埚A溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible3_Aspiration_Weight_A);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "3坩埚B溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible3_Aspiration_Weight_B);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "3坩埚C溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible3_Aspiration_Weight_C);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "3坩埚D溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible3_Aspiration_Weight_D);
                    }

                    if (ConfigData.Crucible4_Status)
                    {
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "坩埚位置设定".Equals(w.ParamName)), 4);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "4坩埚A溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible4_Aspiration_Weight_A);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "4坩埚B溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible4_Aspiration_Weight_B);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "4坩埚C溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible4_Aspiration_Weight_C);
                        ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "4坩埚D溶剂吸液量".Equals(w.ParamName)), ConfigData.Crucible4_Aspiration_Weight_D);
                    }

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "移液配比工位".Equals(w.Name) && "下载参数启动".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.PipetteDistribution);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.PipetteDistribution);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.PipetteDistribution, DeviceStationNumber.GetNumber(DeviceName.PipetteDistribution));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.PipetteDistribution);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.PipetteDistribution}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.PipetteDistribution}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行球磨机1工位设备流程

        /// <summary>
        /// 运行球磨机1工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunBallMilling(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.BallMilling}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.BallMilling}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.BallMilling)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigBallMillingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定转速1".Equals(w.ParamName)), ConfigData.Speed_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定旋转时间1".Equals(w.ParamName)), ConfigData.RotationTime_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定冷却时间1".Equals(w.ParamName)), ConfigData.CoolingTime_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定转速2".Equals(w.ParamName)), ConfigData.Speed_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定旋转时间2".Equals(w.ParamName)), ConfigData.RotationTime_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定冷却时间2".Equals(w.ParamName)), ConfigData.CoolingTime_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定转速3".Equals(w.ParamName)), ConfigData.Speed_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定旋转时间3".Equals(w.ParamName)), ConfigData.RotationTime_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定冷却时间3".Equals(w.ParamName)), ConfigData.CoolingTime_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定间隔时间".Equals(w.ParamName)), ConfigData.IntervalTime);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定冷却时间".Equals(w.ParamName)), ConfigData.BurialTime);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "设定循环次数".Equals(w.ParamName)), ConfigData.LoopNumber);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "切换到自动模式".Equals(w.ParamName)), true);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机1工位".Equals(w.Name) && "下载参数启动".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动模式启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.BallMilling);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.BallMilling);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.BallMilling, DeviceStationNumber.GetNumber(DeviceName.BallMilling));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.BallMilling);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BallMilling}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BallMilling}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行球磨机2工位设备流程

        /// <summary>
        /// 运行球磨机2工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunBallMilling2(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.BallMilling2}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.BallMilling2}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.BallMilling2)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigBallMillingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定转速1".Equals(w.ParamName)), ConfigData.Speed_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定旋转时间1".Equals(w.ParamName)), ConfigData.RotationTime_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定冷却时间1".Equals(w.ParamName)), ConfigData.CoolingTime_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定转速2".Equals(w.ParamName)), ConfigData.Speed_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定旋转时间2".Equals(w.ParamName)), ConfigData.RotationTime_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定冷却时间2".Equals(w.ParamName)), ConfigData.CoolingTime_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定转速3".Equals(w.ParamName)), ConfigData.Speed_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定旋转时间3".Equals(w.ParamName)), ConfigData.RotationTime_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定冷却时间3".Equals(w.ParamName)), ConfigData.CoolingTime_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定间隔时间".Equals(w.ParamName)), ConfigData.IntervalTime);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定冷却时间".Equals(w.ParamName)), ConfigData.BurialTime);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "设定循环次数".Equals(w.ParamName)), ConfigData.LoopNumber);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "切换到自动模式".Equals(w.ParamName)), true);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "球磨机2工位".Equals(w.Name) && "下载参数启动".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动模式启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.BallMilling2);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.BallMilling2);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.BallMilling2, DeviceStationNumber.GetNumber(DeviceName.BallMilling2));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.BallMilling2);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BallMilling2}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BallMilling2}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行颚式破碎机工位设备流程

        /// <summary>
        /// 运行颚式破碎机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunCrusher(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Crusher}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Crusher}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Crusher)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigCrusherDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "破碎机工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), ConfigData.CrushTime);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动模式启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Crusher);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Crusher);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Crusher, DeviceStationNumber.GetNumber(DeviceName.Crusher));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.Crusher);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Crusher}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Crusher}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行刷料机工位设备流程

        /// <summary>
        /// 运行刷料机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunScraping(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Scraping}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Scraping}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Scraping)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigScrapingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "刷料机工位".Equals(w.Name) && "RWG1_Standby2".Equals(w.ParamName)), ++ConfigData.Operate);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "刷料机工位".Equals(w.Name) && "刷料时间S".Equals(w.ParamName)), ConfigData.ScrapingTime);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "刷料启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Scraping);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Scraping);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Scraping, DeviceStationNumber.GetNumber(DeviceName.Scraping));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.Scraping);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Scraping}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Scraping}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行坩埚转换工位设备流程

        /// <summary>
        /// 运行坩埚转换工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunCrucibleConversion(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.CrucibleConversion}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.CrucibleConversion}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.CrucibleConversion)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigScrapingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "坩埚转换位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), ++ConfigData.Operate);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "刷料启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.CrucibleConversion);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.CrucibleConversion);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.CrucibleConversion, DeviceStationNumber.GetNumber(DeviceName.CrucibleConversion));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.CrucibleConversion);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.CrucibleConversion}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.CrucibleConversion}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行自动化电池封装机工位设备流程

        /// <summary>
        /// 运行自动化电池封装机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunPackaging(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Packaging}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Packaging}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Packaging)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigPackagingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-1".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-1".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-1".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-1".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-2".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-2".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-2".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-2".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-3".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-3".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-3".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-3".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-4".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-4".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-4".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-4".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_4);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-5".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-5".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-5".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-5".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_5);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-6".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-6".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-6".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-6".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_6);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-7".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-7".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-7".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-7".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_7);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态目标压力值-8".Equals(w.ParamName)), ConfigData.Solidity_PressureValue_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态保压时间-8".Equals(w.ParamName)), ConfigData.Solidity_PressurizeTime_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态目标压力值-8".Equals(w.ParamName)), ConfigData.Liquid_PressureValue_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态保压时间-8".Equals(w.ParamName)), ConfigData.Liquid_PressurizeTime_8);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定固态封装数量".Equals(w.ParamName)), ConfigData.Solidity_PackageValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "确定固态封装数量".Equals(w.ParamName)), true);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "完成固态压力及时间设置".Equals(w.ParamName)), true);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "设定液态封装数量".Equals(w.ParamName)), ConfigData.Liquid_PackageValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "确定液态封装数量".Equals(w.ParamName)), true);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "完成液态压力及时间设置".Equals(w.ParamName)), true);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "封装机工位".Equals(w.Name) && "下载参数".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "开始封装程序".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Packaging);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Packaging);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Packaging, DeviceStationNumber.GetNumber(DeviceName.Packaging));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.Packaging);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Packaging}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Packaging}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行陶瓷压片机工位设备流程

        /// <summary>
        /// 运行陶瓷压片机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunTabletPress(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.TabletPress}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.TabletPress}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.TabletPress)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigTabletPressDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "程序起始值".Equals(w.ParamName)), ConfigData.StartPressureValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "目标压力值1".Equals(w.ParamName)), ConfigData.TargetPressureValue_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "目标压力值2".Equals(w.ParamName)), ConfigData.TargetPressureValue_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "压力上限值".Equals(w.ParamName)), ConfigData.UpperPressureValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "升压时间".Equals(w.ParamName)), ConfigData.ProgramRunningTime);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "保压时间".Equals(w.ParamName)), ConfigData.PressureHoldTime);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "压片机工位".Equals(w.Name) && "Standby1".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "仪表运行".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.TabletPress);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.TabletPress);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.TabletPress, DeviceStationNumber.GetNumber(DeviceName.TabletPress));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.TabletPress);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.TabletPress}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.TabletPress}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行管式炉工位设备流程

        /// <summary>
        /// 运行管式炉工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunTubeFurnace(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.TubeFurnace}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.TubeFurnace}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.TubeFurnace)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigTubeFurnaceDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP1".Equals(w.ParamName)), ConfigData.Temperature_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t01".Equals(w.ParamName)), ConfigData.Time_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP2".Equals(w.ParamName)), ConfigData.Temperature_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t02".Equals(w.ParamName)), ConfigData.Time_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP3".Equals(w.ParamName)), ConfigData.Temperature_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t03".Equals(w.ParamName)), ConfigData.Time_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP4".Equals(w.ParamName)), ConfigData.Temperature_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t04".Equals(w.ParamName)), ConfigData.Time_4);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP5".Equals(w.ParamName)), ConfigData.Temperature_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t05".Equals(w.ParamName)), ConfigData.Time_5);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP6".Equals(w.ParamName)), ConfigData.Temperature_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t06".Equals(w.ParamName)), ConfigData.Time_6);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP7".Equals(w.ParamName)), ConfigData.Temperature_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t07".Equals(w.ParamName)), ConfigData.Time_7);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP8".Equals(w.ParamName)), ConfigData.Temperature_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t08".Equals(w.ParamName)), ConfigData.Time_8);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP9".Equals(w.ParamName)), ConfigData.Temperature_9);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t09".Equals(w.ParamName)), ConfigData.Time_9);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP10".Equals(w.ParamName)), ConfigData.Temperature_10);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t10".Equals(w.ParamName)), ConfigData.Time_10);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP11".Equals(w.ParamName)), ConfigData.Temperature_11);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t11".Equals(w.ParamName)), ConfigData.Time_11);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP12".Equals(w.ParamName)), ConfigData.Temperature_12);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t12".Equals(w.ParamName)), ConfigData.Time_12);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP13".Equals(w.ParamName)), ConfigData.Temperature_13);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t13".Equals(w.ParamName)), ConfigData.Time_13);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP14".Equals(w.ParamName)), ConfigData.Temperature_14);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t14".Equals(w.ParamName)), ConfigData.Time_14);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP15".Equals(w.ParamName)), ConfigData.Temperature_15);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t15".Equals(w.ParamName)), ConfigData.Time_15);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数SP16".Equals(w.ParamName)), ConfigData.Temperature_16);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "温控参数t16".Equals(w.ParamName)), ConfigData.Time_16);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "进气流量SV".Equals(w.ParamName)), ConfigData.IntakeFlowRate);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-程序最高温度值".Equals(w.ParamName)), ConfigData.ProgramMaxTemperatureValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-洗气循环次数".Equals(w.ParamName)), ConfigData.ScrubbingCirculateCount);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-自动进气流量值".Equals(w.ParamName)), ConfigData.AutoInletFlowValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-自动循环次数".Equals(w.ParamName)), ConfigData.AutoLoopCount);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-舱门开启温度值".Equals(w.ParamName)), ConfigData.DoorOpenTemperatureValue);
                    //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-加热循环程序段号".Equals(w.ParamName)), ConfigData.HeatLoopProgramNumber);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "洗气超时时间".Equals(w.ParamName)), ConfigData.WashingGasTimeoutTime);
                    //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-恒压功能启用".Equals(w.ParamName)), ConfigData.ConstantVoltageEnable);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-真空下限值".Equals(w.ParamName)), ConfigData.VacuumLowerLimitValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-舱门开启压力下限".Equals(w.ParamName)), ConfigData.HatchOpenPressureLowerLimit);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-舱门开启压力上限".Equals(w.ParamName)), ConfigData.HatchOpenPressureUpperLimit);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-炉管压力报警值".Equals(w.ParamName)), ConfigData.FurnaceTubePressureAlarmValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-恒压范围下限".Equals(w.ParamName)), ConfigData.ConstantVoltageRangeLowerLimit);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "自动参数-恒压范围上限".Equals(w.ParamName)), ConfigData.ConstantVoltageRangeUpperLimit);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "配方参数下载".Equals(w.ParamName)), true);

                    Thread.Sleep(5000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "下载系统参数1".Equals(w.ParamName)), true);
                    //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "下载系统参数2".Equals(w.ParamName)), true);
                    //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "管式炉工位".Equals(w.Name) && "初始舱门复位".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.TubeFurnace);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.TubeFurnace);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.TubeFurnace, DeviceStationNumber.GetNumber(DeviceName.TubeFurnace));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.TubeFurnace);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.TubeFurnace}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.TubeFurnace}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行下装炉工位设备流程

        /// <summary>
        /// 运行下装炉工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunBottomFurnace(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.BottomFurnace}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.BottomFurnace}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.BottomFurnace)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigBottomFurnaceDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP1".Equals(w.ParamName)), ConfigData.Temperature_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数01".Equals(w.ParamName)), ConfigData.Time_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP2".Equals(w.ParamName)), ConfigData.Temperature_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数02".Equals(w.ParamName)), ConfigData.Time_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP3".Equals(w.ParamName)), ConfigData.Temperature_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数03".Equals(w.ParamName)), ConfigData.Time_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP4".Equals(w.ParamName)), ConfigData.Temperature_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数04".Equals(w.ParamName)), ConfigData.Time_4);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP5".Equals(w.ParamName)), ConfigData.Temperature_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数05".Equals(w.ParamName)), ConfigData.Time_5);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP6".Equals(w.ParamName)), ConfigData.Temperature_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数06".Equals(w.ParamName)), ConfigData.Time_6);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP7".Equals(w.ParamName)), ConfigData.Temperature_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数07".Equals(w.ParamName)), ConfigData.Time_7);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP8".Equals(w.ParamName)), ConfigData.Temperature_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数08".Equals(w.ParamName)), ConfigData.Time_8);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP9".Equals(w.ParamName)), ConfigData.Temperature_9);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数09".Equals(w.ParamName)), ConfigData.Time_9);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP10".Equals(w.ParamName)), ConfigData.Temperature_10);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数10".Equals(w.ParamName)), ConfigData.Time_10);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP11".Equals(w.ParamName)), ConfigData.Temperature_11);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数11".Equals(w.ParamName)), ConfigData.Time_11);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP12".Equals(w.ParamName)), ConfigData.Temperature_12);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数12".Equals(w.ParamName)), ConfigData.Time_12);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP13".Equals(w.ParamName)), ConfigData.Temperature_13);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数13".Equals(w.ParamName)), ConfigData.Time_13);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP14".Equals(w.ParamName)), ConfigData.Temperature_14);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数14".Equals(w.ParamName)), ConfigData.Time_14);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP15".Equals(w.ParamName)), ConfigData.Temperature_15);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数15".Equals(w.ParamName)), ConfigData.Time_15);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数SP16".Equals(w.ParamName)), ConfigData.Temperature_16);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "温控参数16".Equals(w.ParamName)), ConfigData.Time_16);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "舱门升降速度设置".Equals(w.ParamName)), ConfigData.DoorVelocity);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "自动参数-程序最高温度值".Equals(w.ParamName)), ConfigData.TemperaturePeakValue);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "自动参数-舱门开启温度值".Equals(w.ParamName)), ConfigData.DoorOpenTemperature);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "配方参数下载".Equals(w.ParamName)), true);

                    Thread.Sleep(5000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "下载系统参数1".Equals(w.ParamName)), true);
                    //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "下装炉工位".Equals(w.Name) && "下载系统参数2".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.BottomFurnace);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.BottomFurnace);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.BottomFurnace, DeviceStationNumber.GetNumber(DeviceName.BottomFurnace));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.BottomFurnace);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BottomFurnace}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.BottomFurnace}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行固固测试工位设备流程

        /// <summary>
        /// 运行固固测试工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunSolidSolidTesting(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.SolidSolidTesting}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.SolidSolidTesting}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.SolidSolidTesting)}]".Equals(w.ParamName)), true);

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动模式启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.SolidSolidTesting);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.SolidSolidTesting);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.SolidSolidTesting, DeviceStationNumber.GetNumber(DeviceName.SolidSolidTesting));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.SolidSolidTesting);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.SolidSolidTesting}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.SolidSolidTesting}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行固液测试工位设备流程

        /// <summary>
        /// 运行固液测试工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunSolidLiquidTesting(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.SolidLiquidTesting}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.SolidLiquidTesting}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.SolidLiquidTesting)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigSolidLiquidTestingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "固液测试工位".Equals(w.Name) && "RWG1_Standby1".Equals(w.ParamName)), ConfigData.PeristalticPumpNumber);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动模式启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.SolidLiquidTesting);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.SolidLiquidTesting);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.SolidLiquidTesting, DeviceStationNumber.GetNumber(DeviceName.SolidLiquidTesting));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.SolidLiquidTesting);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.SolidLiquidTesting}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.SolidLiquidTesting}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行电化学测试工位设备流程

        /// <summary>
        /// 运行电化学测试工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunElectroChemistryTesting(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.ElectroChemistryTesting}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.ElectroChemistryTesting}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.ElectroChemistryTesting)}]".Equals(w.ParamName)), true);

                #region 原始逻辑备份

                //// 发送配置参数命令
                //var Check = Global.ElecMachines.InitConnect();
                //if (Check.Item1)
                //{
                //    // 获取参数配置信息
                //    var ConfigData = BisExpConfigElectroChemistryTestingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                //    if (ConfigData != null)
                //    {
                //        // 设置实验配置
                //        Global.ElecMachines.StartExp(int.Parse(ConfigData.SelExpId), ConfigData);
                //    }
                //}
                //else
                //{
                //    // 创建运行记录
                //    CreateExpRunLog(ExpRecordData, $"{DeviceName.ElectroChemistryTesting}工位设备初始化失败, 无法工作 (Error: {Check.Item2})");

                //    return;
                //}

                //#endregion

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.ElectroChemistryTesting);

                //// 检测返回结果
                //bool CheckResult = false;

                //bool IsExecuting = true;
                //JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();
                //List<Helper.ElecMachinesHelper.RunRecordData> RunRecordData = new List<Helper.ElecMachinesHelper.RunRecordData>();
                //List<bis_experiment_runlog_electrochemistrytest> InsertModel = new List<bis_experiment_runlog_electrochemistrytest>();
                //bis_experiment_runlog_electrochemistrytest InsertData = new bis_experiment_runlog_electrochemistrytest();
                //do
                //{
                //    // 单步运行实验流程
                //    try
                //    {
                //        RunRecordData = Global.ElecMachines.SingleStepRunExp();
                //        if (RunRecordData.Count > 0)
                //        {
                //            // 记录实验数据
                //            RunRecordData.ForEach(item =>
                //            {
                //                InsertData = ConvertHelper.ConvertObject<bis_experiment_runlog_electrochemistrytest>(item);
                //                InsertData.Id = Guid.NewGuid().ToString().ToUpper();
                //                InsertData.ExpId = ExpRecordData.Id;
                //                InsertData.ExpName = ExpRecordData.Name;
                //                InsertData.CreateTime = DateTime.Now;
                //                InsertData.Del_Flag = 0;

                //                InsertModel.Add(InsertData);
                //            });
                //            _ = BisExperimentRunLogElectroChemistryTestDao.InsertMany(InsertModel).Result;
                //        }
                //    }
                //    catch (Exception ex)
                //    {
                //        Console.WriteLine(ex);
                //    }

                //    // 检查是否正在运行实验
                //    CheckResult = Global.ElecMachines.IsExperimenting();
                //    if (!CheckResult)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigElectroChemistryTestingDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    #region 保存参数配置信息

                    string ConfigFilePath = $"{AppDomain.CurrentDomain.SetupInformation.ApplicationBase}\\ElectroChemistryTestingConfig.txt";
                    if (File.Exists(ConfigFilePath)) { File.Delete(ConfigFilePath); }
                    using FileStream fs = new FileStream(ConfigFilePath, FileMode.Create, FileAccess.ReadWrite);
                    using StreamWriter sw = new StreamWriter(fs);

                    sw.Write($"SelExpId|{ConfigData.SelExpId}\n");
                    sw.Write($"SelExpName|{ConfigData.SelExpName}\n");
                    sw.Write($"TimePerPoint|{ConfigData.TimePerPoint}\n");
                    sw.Write($"ContinueTime|{ConfigData.ContinueTime}\n");
                    sw.Write($"IsUseInitialPotential|{ConfigData.IsUseInitialPotential}\n");
                    sw.Write($"InitialPotential|{ConfigData.InitialPotential}\n");
                    sw.Write($"InitialPotentialVSType|{ConfigData.InitialPotentialVSType}\n");
                    sw.Write($"TopPotential1|{ConfigData.TopPotential1}\n");
                    sw.Write($"TopPotential1VSType|{ConfigData.TopPotential1VSType}\n");
                    sw.Write($"TopPotential2|{ConfigData.TopPotential2}\n");
                    sw.Write($"TopPotential2VSType|{ConfigData.TopPotential2VSType}\n");
                    sw.Write($"IsUseFinallyPotential|{ConfigData.IsUseFinallyPotential}\n");
                    sw.Write($"FinallyPotential|{ConfigData.FinallyPotential}\n");
                    sw.Write($"FinallyPotentialVSType|{ConfigData.FinallyPotentialVSType}\n");
                    sw.Write($"IsVoltageRandAuto|{ConfigData.IsVoltageRandAuto}\n");
                    sw.Write($"VoltageRand|{ConfigData.VoltageRand}\n");
                    sw.Write($"IsCurrentRandAuto|{ConfigData.IsCurrentRandAuto}\n");
                    sw.Write($"CurrentRand|{ConfigData.CurrentRand}\n");
                    sw.Write($"IsVolEIS|{ConfigData.IsVolEIS}\n");
                    sw.Write($"Voltage|{ConfigData.Voltage}\n");
                    sw.Write($"VoltageVSType|{ConfigData.VoltageVSType}\n");
                    sw.Write($"ScanRate|{ConfigData.ScanRate}\n");
                    sw.Write($"CycleCount|{ConfigData.CycleCount}\n");
                    sw.Write($"StepHeight|{ConfigData.StepHeight}\n");
                    sw.Write($"StepTime|{ConfigData.StepTime}\n");
                    sw.Write($"Current|{ConfigData.Current}\n");
                    sw.Write($"StartFreq|{ConfigData.StartFreq}\n");
                    sw.Write($"EndFreq|{ConfigData.EndFreq}\n");
                    sw.Write($"Amplitude|{ConfigData.Amplitude}\n");
                    sw.Write($"IntervalType|{ConfigData.IntervalType}\n");
                    sw.Write($"PointCount|{ConfigData.PointCount}\n");

                    sw.Flush();
                    sw.Close();

                    #endregion
                }

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.ElectroChemistryTesting);

                // 运行电化学测试工具
                using (Process process = new Process())
                {
                    // 设置 EXE 文件路径
                    process.StartInfo.FileName = "Robot.ElectroChemistryTest.exe";

                    // 启动进程
                    process.Start();

                    // 等待进程完成
                    process.WaitForExit();
                }

                // 记录实验数据
                List<(string, string)> ResultParamData = new List<(string, string)>();
                List<bis_experiment_runlog_electrochemistrytest> InsertModel = new List<bis_experiment_runlog_electrochemistrytest>();
                bis_experiment_runlog_electrochemistrytest InsertData = new bis_experiment_runlog_electrochemistrytest();

                string ResultFilePath = $"{AppDomain.CurrentDomain.SetupInformation.ApplicationBase}\\ElectroChemistryTestingResult.txt";
                using (StreamReader Reader = new StreamReader(ResultFilePath))
                {
                    string Line;
                    string[] Data;
                    string[] ParamData;
                    while ((Line = Reader.ReadLine()) != null)
                    {
                        Data = Line.Split('|');
                        ResultParamData = new List<(string, string)>();
                        foreach (var item in Data)
                        {
                            ParamData = item.Split("=");
                            ResultParamData.Add((ParamData[0], ParamData[1]));
                        }
                        InsertData = new bis_experiment_runlog_electrochemistrytest
                        {
                            Id = Guid.NewGuid().ToString().ToUpper(),
                            ExpId = ExpRecordData.Id,
                            ExpName = ExpRecordData.Name,
                            Capacity = ResultParamData.FirstOrDefault(w => "Capacity".Equals(w.Item1)).Item2,
                            Current = ResultParamData.FirstOrDefault(w => "Current".Equals(w.Item1)).Item2,
                            E = ResultParamData.FirstOrDefault(w => "E".Equals(w.Item1)).Item2,
                            EDC = ResultParamData.FirstOrDefault(w => "EDC".Equals(w.Item1)).Item2,
                            Energy = ResultParamData.FirstOrDefault(w => "Energy".Equals(w.Item1)).Item2,
                            Freq = ResultParamData.FirstOrDefault(w => "Freq".Equals(w.Item1)).Item2,
                            I = ResultParamData.FirstOrDefault(w => "I".Equals(w.Item1)).Item2,
                            JiaoDu = ResultParamData.FirstOrDefault(w => "JiaoDu".Equals(w.Item1)).Item2,
                            LstTime = ResultParamData.FirstOrDefault(w => "LstTime".Equals(w.Item1)).Item2,
                            P = ResultParamData.FirstOrDefault(w => "P".Equals(w.Item1)).Item2,
                            Phase = ResultParamData.FirstOrDefault(w => "Phase".Equals(w.Item1)).Item2,
                            Q = ResultParamData.FirstOrDefault(w => "Q".Equals(w.Item1)).Item2,
                            Time = ResultParamData.FirstOrDefault(w => "Time".Equals(w.Item1)).Item2,
                            Voltage = ResultParamData.FirstOrDefault(w => "Voltage".Equals(w.Item1)).Item2,
                            Z = ResultParamData.FirstOrDefault(w => "Z".Equals(w.Item1)).Item2,
                            Zre = ResultParamData.FirstOrDefault(w => "Zre".Equals(w.Item1)).Item2,
                            Zim = ResultParamData.FirstOrDefault(w => "Zim".Equals(w.Item1)).Item2,
                            ZValue = ResultParamData.FirstOrDefault(w => "ZValue".Equals(w.Item1)).Item2,
                            CreateTime = DateTime.Parse(ResultParamData.FirstOrDefault(w => "CreateTime".Equals(w.Item1)).Item2),
                            Del_Flag = 0
                        };
                        InsertModel.Add(InsertData);
                    }
                    _ = BisExperimentRunLogElectroChemistryTestDao.InsertMany(InsertModel).Result;
                }

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.ElectroChemistryTesting}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.ElectroChemistryTesting}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行XRD测试仪工位设备流程

        /// <summary>
        /// 运行XRD测试仪工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunXRDTesting(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.XRDDevice}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.XRDDevice}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.XRDDevice)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigXRDTestDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "高压设定_千伏".Equals(w.ParamName)), ConfigData.HighVoltageKV);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "高压设定_毫安".Equals(w.ParamName)), ConfigData.HighVoltagemA);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "设定参数1_起始角度".Equals(w.ParamName)), ConfigData.StartAngle);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "设定参数1_终止角度".Equals(w.ParamName)), ConfigData.EndAngle);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "设定参数2_测量速度".Equals(w.ParamName)), ConfigData.MeasureVelocity);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "XRD测试工位".Equals(w.Name) && "设定参数2_测量步宽".Equals(w.ParamName)), ConfigData.MeasureStep);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "自动启动".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.XRDDevice);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.XRDDevice);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.XRDDevice, DeviceStationNumber.GetNumber(DeviceName.XRDDevice));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.XRDDevice);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.XRDDevice}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.XRDDevice}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #region 运行自动化烘干机工位设备流程

        /// <summary>
        /// 运行自动化烘干机工位设备流程
        /// </summary>
        /// <param name="ExpRecordData">实验记录数据</param>
        /// <param name="DeviceConfig">控制命令</param>
        public void RunOven(bis_experiment_record ExpRecordData, List<bis_device_config> DeviceConfig)
        {
            Console.WriteLine($"开始运行{DeviceName.Oven}工位设备流程");
            try
            {
                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"开始运行{DeviceName.Oven}工位设备");

                // 发送工位有效信号命令
                ExecuteCmd(DeviceConfig.FirstOrDefault(w => "总控制信号".Equals(w.Name) && $"工位有效信号[{DeviceStationNumber.GetNumber(DeviceName.Oven)}]".Equals(w.ParamName)), true);

                #region 发送配置参数命令

                // 获取参数配置信息
                var ConfigData = BisExpConfigOvenDao.QuerySingle(w => w.Del_Flag == 0 && w.ExpId.Equals(ExpRecordData.Id)).Result;
                if (ConfigData != null)
                {
                    // 发送配置参数命令
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间1".Equals(w.ParamName)), ConfigData.Time_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度1".Equals(w.ParamName)), ConfigData.Temperature_1);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速1".Equals(w.ParamName)), ConfigData.Speed_1);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间2".Equals(w.ParamName)), ConfigData.Time_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度2".Equals(w.ParamName)), ConfigData.Temperature_2);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速2".Equals(w.ParamName)), ConfigData.Speed_2);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间3".Equals(w.ParamName)), ConfigData.Time_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度3".Equals(w.ParamName)), ConfigData.Temperature_3);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速3".Equals(w.ParamName)), ConfigData.Speed_3);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间4".Equals(w.ParamName)), ConfigData.Time_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度4".Equals(w.ParamName)), ConfigData.Temperature_4);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速4".Equals(w.ParamName)), ConfigData.Speed_4);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间5".Equals(w.ParamName)), ConfigData.Time_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度5".Equals(w.ParamName)), ConfigData.Temperature_5);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速5".Equals(w.ParamName)), ConfigData.Speed_5);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间6".Equals(w.ParamName)), ConfigData.Time_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度6".Equals(w.ParamName)), ConfigData.Temperature_6);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速6".Equals(w.ParamName)), ConfigData.Speed_6);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间7".Equals(w.ParamName)), ConfigData.Time_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度7".Equals(w.ParamName)), ConfigData.Temperature_7);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速7".Equals(w.ParamName)), ConfigData.Speed_7);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间8".Equals(w.ParamName)), ConfigData.Time_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度8".Equals(w.ParamName)), ConfigData.Temperature_8);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速8".Equals(w.ParamName)), ConfigData.Speed_8);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间9".Equals(w.ParamName)), ConfigData.Time_9);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度9".Equals(w.ParamName)), ConfigData.Temperature_9);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速9".Equals(w.ParamName)), ConfigData.Speed_9);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间10".Equals(w.ParamName)), ConfigData.Time_11);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度10".Equals(w.ParamName)), ConfigData.Temperature_11);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速10".Equals(w.ParamName)), ConfigData.Speed_11);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间12".Equals(w.ParamName)), ConfigData.Time_12);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度12".Equals(w.ParamName)), ConfigData.Temperature_12);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速12".Equals(w.ParamName)), ConfigData.Speed_12);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间13".Equals(w.ParamName)), ConfigData.Time_13);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度13".Equals(w.ParamName)), ConfigData.Temperature_13);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速13".Equals(w.ParamName)), ConfigData.Speed_13);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间14".Equals(w.ParamName)), ConfigData.Time_14);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度14".Equals(w.ParamName)), ConfigData.Temperature_14);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速14".Equals(w.ParamName)), ConfigData.Speed_14);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间15".Equals(w.ParamName)), ConfigData.Time_15);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度15".Equals(w.ParamName)), ConfigData.Temperature_15);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速15".Equals(w.ParamName)), ConfigData.Speed_15);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间16".Equals(w.ParamName)), ConfigData.Time_16);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度16".Equals(w.ParamName)), ConfigData.Temperature_16);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速16".Equals(w.ParamName)), ConfigData.Speed_16);

                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定温度_固定".Equals(w.ParamName)), ConfigData.SettingTemperature);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定转速_固定".Equals(w.ParamName)), ConfigData.SettingRotateSpeed);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "设定时间_固定".Equals(w.ParamName)), ConfigData.SettingTime);

                    Thread.Sleep(3000);
                    ExecuteCmd(DeviceConfig.FirstOrDefault(w => "烘箱工位".Equals(w.Name) && "下载参数触发".Equals(w.ParamName)), true);
                }

                #endregion

                #region 原始逻辑备份

                //// 发送启动命令
                //ExecuteCmd(DeviceConfig.FirstOrDefault(w => "启动触发".Equals(w.ParamName)));

                //// 开始检测设备预警
                //CheckDeviceWarning(DeviceConfig, DeviceName.Oven);

                //// 检测是否正在进行实验命令
                //bis_device_config CheckCmd = DeviceConfig.FirstOrDefault(w => "设备状态".Equals(w.ParamName));

                //// 检测返回结果
                //ValueModel CheckResult = new ValueModel();

                //bool IsExecuting = true;
                //do
                //{
                //    // 获取结果
                //    CheckResult = Global.SaveNodeData.FirstOrDefault(w => w.Value.Tag.Equals(CheckCmd.ParamId)).Value;
                //    if (CheckResult.Value == null)
                //    {
                //        // 标记为已结束状态
                //        IsExecuting = false;
                //    }
                //    else
                //    {
                //        // 如果设备状态为空闲时
                //        if (int.Parse(CheckResult.Value) == 1)
                //        {
                //            // 标记为已结束状态
                //            IsExecuting = false;
                //        }
                //    }

                //    // 等待1秒，继续判断
                //    Thread.Sleep(1000);

                //} while (IsExecuting == true);

                //// 跳出循序时表示执行结束，进入实验终止阶段

                #endregion

                // 开始检测设备预警
                CheckDeviceWarning(DeviceConfig, DeviceName.Oven);

                // 移动AGV小车至指定位置
                MoveAgvVehicle(ExpRecordData, DeviceConfig, DeviceName.Oven, DeviceStationNumber.GetNumber(DeviceName.Oven));

                // 检查设备是否处于待机中
                CheckDeviceIsStandby(DeviceConfig, DeviceName.Oven);

                // 停止检测设备预警
                IsCheckDevice = false;

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Oven}工位设备运行结束");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

                // 创建运行记录
                CreateExpRunLog(ExpRecordData, $"{DeviceName.Oven}工位设备运行发生异常, 已提前结束");
            }
        }

        #endregion

        #endregion

        #endregion

        #region 检查实验任务队列

        /// <summary>
        /// 检查实验任务队列
        /// </summary>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> CheckExperimentQueue()
        {
            Console.WriteLine("\n检查实验任务队列：CheckExperimentQueue");

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            DateTime now = DateTime.Now;
            int Check = 0;

            #region 检查实验数据

            // 检查是否存在队列中实验数据
            Check = await BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0 && "10".Equals(w.Status));
            if (Check <= 0)
            {
                Console.WriteLine("暂无实验队列数据");

                return new JsonResult(new ResultModel
                {
                    Msg = "暂无实验队列数据"
                });
            }

            // 检查是否存在进行中实验数据
            Check = await BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0 && "20".Equals(w.Status));
            if (Check > 0)
            {
                Console.WriteLine("实验队列存在进行中的实验");

                return new JsonResult(new ResultModel
                {
                    Msg = "实验队列存在进行中的实验"
                });
            }

            #endregion

            // 实验队列中存在数据且暂无进行中的实验，准备按照实验设置的顺序执行排在第一位的实验
            var ExpData = await BisExperimentRecordDao.QueryByWherePage(0, 1, w => w.Del_Flag == 0 && "10".Equals(w.Status), o => o.Sort);
            if (ExpData != null && ExpData.Count > 0)
            {
                bis_experiment_record FirstExpData = ExpData.FirstOrDefault();

                // 检查实验所需设备是否可用
                ResultModel CheckResult = CheckExpRequiredDeviceStatus(FirstExpData);
                if (!CheckResult.Success)
                {
                    return new JsonResult(CheckResult);
                }

                // 更新实验记录状态为进行中
                UpdateExpStatus(FirstExpData.Id, "20");

                // 执行实验
                await Task.Run(async () =>
                {
                    await InitExperiment(FirstExpData);
                });
            }

            return new JsonResult(new ResultModel
            {
                Msg = "实验正在进行中",
            });
        }

        #endregion

        #region 生成实验任务编号

        /// <summary>
        /// 生成实验任务编号
        /// </summary>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> CreateExperimentNumber()
        {
            await Task.Run(() => { Console.WriteLine("\n生成实验任务编号：CreateExperimentNumber"); });

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            DateTime now = DateTime.Now;
            int Year = now.Year;
            int Month = now.Month;
            int Day = now.Day;

            // 获取本日创建的实验任务数量
            int Count = BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0
                && Year == w.CreateTime.Value.Year
                && Month == w.CreateTime.Value.Month
                && Day == w.CreateTime.Value.Day).Result;

            Console.WriteLine($"Count: {Count}");

            string result = $"{now:yyyyMMdd}{TextHelper.FormatIntToString((++Count).ToString(), "0", 3)}";

            Console.WriteLine($"Result: {result}");

            return new JsonResult(new ResultModel
            {
                Data = result,
            });
        }

        #endregion

        #region 获取实验统计数据

        /// <summary>
        /// 获取实验统计数据
        /// </summary>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> ExperimentStatistics()
        {
            Console.WriteLine("\n获取实验统计数据：ExperimentStatistics");

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            int count = 0;
            List<PieDataModel> result = new List<PieDataModel>();

            count = await BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0 && "20".Equals(w.Status));
            result.Add(new PieDataModel
            {
                Name = $"正在进行({count})",
                Value = count
            });

            count = await BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0 && "10".Equals(w.Status));
            result.Add(new PieDataModel
            {
                Name = $"队列中({count})",
                Value = count
            });

            //count = await BisExperimentRecordDao.QueryCount(w => w.Del_Flag == 0 && "30".Equals(w.Status));
            //result.Add(new PieDataModel
            //{
            //    Name = $"已完成({count})",
            //    Value = count
            //});

            return new JsonResult(new ResultModel
            {
                Data = result,
                Data2 = result.Sum(s => s.Value)
            });
        }

        #endregion

        #region 获取当前实验预计完成时长

        /// <summary>
        /// 获取当前实验预计完成时长
        /// </summary>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> GetThisExpectedCompletionTime()
        {
            Console.WriteLine("\n获取当前实验预计完成时长：GetThisExpectedCompletionTime");

            DateTime now = DateTime.Now;
            int totalTime = 0;

            var result = await BisExperimentRecordDao.QueryByWhere(w => w.Del_Flag == 0 && "20".Equals(w.Status));
            if (result != null)
            {
                foreach (var item in result)
                {
                    totalTime += (int)TimeSpan.FromMinutes((item.ExpectedWorkingHours - (now - item.ExpStartTime).Value.TotalMinutes).Value).TotalSeconds;
                }
            }

            // 秒 转换为 时分秒
            int seconds = totalTime % 60;
            int minutes = totalTime / 60 % 60;
            int hours = totalTime / 3600 % 60;
            //string date = string.Format("{0:00}{1:00}{2:00}", hours + ",", minutes + ",", seconds);
            string date = $"{(hours > 0 ? hours : 0):D2},{(minutes > 0 ? minutes : 0):D2},{(seconds > 0 ? seconds : 0):D2}";

            return new JsonResult(new ResultModel
            {
                Data = date,
            });
        }

        #endregion

        #region 获取累计实验工作时长

        /// <summary>
        /// 获取累计实验工作时长
        /// </summary>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> Accumulateworkduration()
        {
            Console.WriteLine("\n获取累计实验工作时长：Accumulateworkduration");

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }
            #endregion

            // 初始化数据查询表达式
            StringBuilder strBuilder = new StringBuilder();

            // 任务进程总览-累计实验工作时长
            strBuilder.Append($" SELECT SUM(TIMEDIFF(ExpEndTime,ExpStartTime)) AS Seconds FROM bis_experiment_record ");
            strBuilder.Append($" WHERE Del_Flag = 0 AND Status = '30' ");

            // 调用sql
            List<AccumulateworkdurationModel> result = await BisExperimentRecordDao.QueryBySql<AccumulateworkdurationModel>(strBuilder.ToString());

            // 秒 转换为 时分秒
            int totalTime = result[0].Seconds;
            int seconds = totalTime % 60;
            int minutes = totalTime / 60 % 60;
            int hours = totalTime / 3600 % 60;
            //string date = string.Format("{0:00}{1:00}{2:00}", hours + ",", minutes + ",", seconds);
            string date = $"{(hours > 0 ? hours : 0):D2},{(minutes > 0 ? minutes : 0):D2},{(seconds > 0 ? seconds : 0):D2}";

            // 返回结果
            return new JsonResult(new ResultModel
            {
                Data = date,
            });
        }

        #endregion     

        #region 获取实验模板列表

        /// <summary>
        /// 获取实验模板列表
        /// </summary>
        /// <param name="param">搜索条件</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> ExperimentTemplateList(SearchModel param)
        {
            Console.WriteLine("\n获取实验模板列表：ExperimentTemplateList");

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            // 初始化数据查询表达式
            Expression<Func<bis_experiment_template, bool>> expression = w => w.Del_Flag == 0;

            Console.WriteLine($"Name：{param.Name}");
            if (!string.IsNullOrEmpty(param.Name))
            {
                expression = expression.And(w => w.Name.Contains(param.Name));
            }

            Console.WriteLine($"Number：{param.Number}");
            if (!string.IsNullOrEmpty(param.Number))
            {
                expression = expression.And(w => w.Number.Contains(param.Number));
            }

            Console.WriteLine($"Type：{param.Type}");
            if (!string.IsNullOrEmpty(param.Type))
            {
                string[] conditions = param.Type.Split(',');
                Expression<Func<bis_experiment_template, bool>> expressionSub = w => w.Type.Equals(conditions.GetValue(0).ToString());
                expressionSub = expressionSub.And(w => w.Del_Flag == 0);
                for (int i = 1; i < conditions.Length; i++)
                {
                    var statusTmp = conditions.GetValue(i).ToString();
                    expressionSub = expressionSub.Or(w => w.Type.Equals(statusTmp));
                }
                expression = expression.And(expressionSub);
            }

            dynamic result = null;
            if (param.Page != null && param.Limit != null)
            {
                result = await BisExperimentTemplateDao.QueryByWherePage(param.Page.Value, param.Limit.Value, expression, o => o.Sort, OrderByType.Asc);
            }
            else
            {
                result = await BisExperimentTemplateDao.QueryByWhere(expression, o => o.Sort, OrderByType.Asc);
            }
            var count = await BisExperimentTemplateDao.QueryCount(expression);

            return new JsonResult(new ResultModel
            {
                Count = count,
                Data = result
            });
        }

        #endregion

        #region 获取实验模板详情

        /// <summary>
        /// 获取实验模板详情
        /// </summary>
        /// <param name="param">搜索条件</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> ExperimentTemplateDetail(SearchModel param)
        {
            Console.WriteLine("\n获取实验模板详情：ExperimentTemplateDetail");

            #region 参数校验

            Console.WriteLine($"Id：{param.Id}");
            if (string.IsNullOrEmpty(param.Id))
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion

            // 获取详情数据
            var result = await BisExperimentTemplateDao.QuerySingle(w => w.Del_Flag == 0 && w.Id.Equals(param.Id));
            if (result != null)
            {
                result.ConfigList = await BisExperimentTemplateConfigDao.QueryByWhere(w => w.Del_Flag == 0 && w.ExpTemplateId.Equals(param.Id));
            }

            return new JsonResult(new ResultModel
            {
                Data = result
            });
        }

        #endregion

        #region 提交实验模板信息

        /// <summary>
        /// 提交实验模板信息
        /// </summary>
        /// <param name="param">更新参数集</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> SubmitExperimentTemplate(UpdateModel param)
        {
            Console.WriteLine("\n提交实验模板信息：SubmitExperimentTemplate");

            #region 参数、数据校验

            Console.WriteLine($"ExpTemplateData：{param.ExpTemplateData}");
            Console.WriteLine($"ExpTemplateConfigData：{param.ExpTemplateConfigData}");
            Console.WriteLine($"NodeConfigData：{param.NodeConfigData}");
            Console.WriteLine($"ExpConfigNodeData：{param.ExpConfigNodeData}");

            if (param.ExpTemplateData == null ||
                param.ExpTemplateConfigData == null ||
                param.ExpConfigNodeData == null)
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion 

            #region 获取所需数据

            #region 获取登录用户相关信息

            string userId = string.Empty;
            string userName = string.Empty;
            string orgId = string.Empty;
            string orgName = string.Empty;
            try
            {
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userName = Accessor.HttpContext.User.Claims.First(i => i.Type == "userName").Value;
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                orgName = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgName").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            #endregion

            #region 数据提交

            DateTime now = DateTime.Now;
            Guid guid = Guid.NewGuid();
            string newId = guid.ToString().ToUpper();

            int result = 0;

            // 如果Guid为空时则新增，否则为编辑
            if (string.IsNullOrEmpty(param.ExpTemplateData.Id))
            {
                var model = new bis_experiment_template()
                {
                    Id = newId,
                    Type = param.ExpTemplateData.Type,
                    Name = param.ExpTemplateData.Name,
                    Number = param.ExpTemplateData.Number,
                    Sort = param.ExpTemplateData.Sort,
                    Remark = param.ExpTemplateData.Remark,
                    OrgGuid = orgId,
                    OrgName = orgName,
                    CreateUser = userId,
                    CreateUserName = userName,
                    CreateTime = now,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                    Del_Flag = 0
                };
                result += await BisExperimentTemplateDao.Insert(model);

                var configModel = new bis_experiment_template_config()
                {
                    Id = Guid.NewGuid().ToString().ToUpper(),
                    ExpTemplateId = model.Id,
                    Type = param.ExpTemplateConfigData.Type,
                    ExpectedWorkingHours = param.ExpTemplateConfigData.ExpectedWorkingHours,
                    FlowPathConfig = param.ExpTemplateConfigData.FlowPathConfig,
                    AssemblyConfig = param.ExpTemplateConfigData.AssemblyConfig,
                    Remark = param.ExpTemplateConfigData.Remark,
                    OrgGuid = orgId,
                    OrgName = orgName,
                    CreateUser = userId,
                    CreateUserName = userName,
                    CreateTime = now,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                    Del_Flag = 0
                };
                result += await BisExperimentTemplateConfigDao.Insert(configModel);

                if (param.ExpConfigNodeData != null)
                {
                    // 按时间进行排序
                    param.ExpConfigNodeData = param.ExpConfigNodeData.OrderBy(o => o.CreateTime).ToList();

                    // 节点排序号
                    int SortValue = 1;

                    param.ExpConfigNodeData.ForEach(item =>
                    {
                        item.Id = Guid.NewGuid().ToString().ToUpper();
                        item.ExpId = configModel.Id;
                        item.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                        item.Sort = SortValue;
                        item.Remark = "";
                        item.CreateUser = userId;
                        item.CreateUserName = userName;
                        item.CreateTime = now;
                        item.UpdateUser = userId;
                        item.UpdateUserName = userName;
                        item.UpdateTime = now;
                        item.Del_Flag = 0;

                        SortValue++;    // 排序号值加一
                    });
                    result += await BisExpConfigNodeDao.InsertMany(param.ExpConfigNodeData);
                }

                #region 创建关联节点配置数据

                if (param.NodeConfigData != null)
                {
                    param.NodeConfigData.ForEach(async item =>
                    {
                        switch (item.Name)
                        {
                            case DeviceName.Capper:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_capper>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCapperDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Capper2:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_capper_two>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCapperTwoDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.MaterialPositioningTable:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_materialpositiontable>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigMaterialPositionTableDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.UltrasonicCleaningMachine:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ultrasoniccleaningmachine>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigUltrasonicCleaningMachineDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.PrecisionBalance:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_balance>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBalanceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.FlourBlending:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_flourblending>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigFlourBlendingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.PipetteDistribution:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_pipettedistribution>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigPipetteDistributionDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BallMilling:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ballmilling>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBallMillingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BallMilling2:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ballmilling_two>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBallMillingTwoDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Crusher:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_crusher>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCrusherDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.TabletPress:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_tabletpress>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigTabletPressDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Scraping:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_scraping>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigScrapingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.CrucibleConversion:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_crucibleconversion>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCrucibleConversionDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Packaging:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_packaging>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigPackagingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.TubeFurnace:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_tubefurnace>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<TubeFurnaceModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Time_1 = ParamData[0].Time;

                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Time_2 = ParamData[1].Time;

                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Time_3 = ParamData[2].Time;

                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Time_4 = ParamData[3].Time;

                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Time_5 = ParamData[4].Time;

                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Time_6 = ParamData[5].Time;

                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Time_7 = ParamData[6].Time;

                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Time_8 = ParamData[7].Time;

                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Time_9 = ParamData[8].Time;

                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Time_10 = ParamData[9].Time;

                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Time_11 = ParamData[10].Time;

                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Time_12 = ParamData[11].Time;

                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Time_13 = ParamData[12].Time;

                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Time_14 = ParamData[13].Time;

                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Time_15 = ParamData[14].Time;

                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Time_16 = ParamData[15].Time;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigTubeFurnaceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BottomFurnace:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_bottomfurnace>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<TubeFurnaceModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Time_1 = ParamData[0].Time;

                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Time_2 = ParamData[1].Time;

                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Time_3 = ParamData[2].Time;

                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Time_4 = ParamData[3].Time;

                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Time_5 = ParamData[4].Time;

                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Time_6 = ParamData[5].Time;

                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Time_7 = ParamData[6].Time;

                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Time_8 = ParamData[7].Time;

                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Time_9 = ParamData[8].Time;

                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Time_10 = ParamData[9].Time;

                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Time_11 = ParamData[10].Time;

                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Time_12 = ParamData[11].Time;

                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Time_13 = ParamData[12].Time;

                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Time_14 = ParamData[13].Time;

                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Time_15 = ParamData[14].Time;

                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Time_16 = ParamData[15].Time;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBottomFurnaceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.SolidLiquidTesting:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_solidliquidtesting>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigSolidLiquidTestingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.ElectroChemistryTesting:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    bis_expconfig_electrochemistrytesting ConfigData = new bis_expconfig_electrochemistrytesting();
                                    switch (SaveData.SelExpId)
                                    {
                                        // 实验配置-0 开路电位(电分析)
                                        case "0":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_kldw"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                            }
                                            break;
                                        // 实验配置-1 线性扫描伏安法(LSV)
                                        case "1":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xxsmfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-2 循环伏安法
                                        case "2":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xhfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-3 循环伏安法(多循环)
                                        case "3":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xhfafdxh"].ToString());
                                                SaveData.IsUseInitialPotential = ConfigData.IsUseInitialPotential;
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.TopPotential2 = ConfigData.TopPotential2;
                                                SaveData.TopPotential2VSType = ConfigData.TopPotential2VSType;
                                                SaveData.IsUseFinallyPotential = ConfigData.IsUseFinallyPotential;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.CycleCount = ConfigData.CycleCount;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-4 恒电位
                                        case "4":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_hdw"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-5 恒电流
                                        case "5":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_hdl"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                                SaveData.Current = ConfigData.Current;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-6 交流阻抗(电压)
                                        case "6":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jlzkdy"].ToString());
                                                SaveData.IsVolEIS = ConfigData.IsVolEIS;
                                                SaveData.StartFreq = ConfigData.StartFreq;
                                                SaveData.EndFreq = ConfigData.EndFreq;
                                                SaveData.Amplitude = ConfigData.Amplitude;
                                                SaveData.IntervalType = ConfigData.IntervalType;
                                                SaveData.PointCount = ConfigData.PointCount;
                                                SaveData.Voltage = ConfigData.Voltage;
                                                SaveData.VoltageVSType = ConfigData.VoltageVSType;
                                            }
                                            break;
                                        // 实验配置-7 交流阻抗(电流)
                                        case "7":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jlzkdl"].ToString());
                                                SaveData.IsVolEIS = ConfigData.IsVolEIS;
                                                SaveData.StartFreq = ConfigData.StartFreq;
                                                SaveData.EndFreq = ConfigData.EndFreq;
                                                SaveData.Amplitude = ConfigData.Amplitude;
                                                SaveData.IntervalType = ConfigData.IntervalType;
                                                SaveData.PointCount = ConfigData.PointCount;
                                                SaveData.Voltage = ConfigData.Voltage;
                                            }
                                            break;
                                        // 实验配置-8 阶梯循环伏安法
                                        case "8":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxhfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-9 阶梯循环伏安法(多循环)
                                        case "9":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxhfafdxh"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.TopPotential2 = ConfigData.TopPotential2;
                                                SaveData.TopPotential2VSType = ConfigData.TopPotential2VSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-10 阶梯线性扫描伏安法(SLSV)
                                        case "10":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxxsmfafslsv"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-11 Tafel
                                        case "11":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_tafel"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigElectroChemistryTestingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.XRDDevice:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_xrdtest>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigXRDTestDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Oven:
                                {
                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_oven>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<OvenModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Time_1 = ParamData[0].Time;
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Speed_1 = ParamData[0].Speed;

                                        SaveData.Time_2 = ParamData[1].Time;
                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Speed_2 = ParamData[1].Speed;

                                        SaveData.Time_3 = ParamData[2].Time;
                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Speed_3 = ParamData[2].Speed;

                                        SaveData.Time_4 = ParamData[3].Time;
                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Speed_4 = ParamData[3].Speed;

                                        SaveData.Time_5 = ParamData[4].Time;
                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Speed_5 = ParamData[4].Speed;

                                        SaveData.Time_6 = ParamData[5].Time;
                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Speed_6 = ParamData[5].Speed;

                                        SaveData.Time_7 = ParamData[6].Time;
                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Speed_7 = ParamData[6].Speed;

                                        SaveData.Time_8 = ParamData[7].Time;
                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Speed_8 = ParamData[7].Speed;

                                        SaveData.Time_9 = ParamData[8].Time;
                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Speed_9 = ParamData[8].Speed;

                                        SaveData.Time_10 = ParamData[9].Time;
                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Speed_10 = ParamData[9].Speed;

                                        SaveData.Time_11 = ParamData[10].Time;
                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Speed_11 = ParamData[10].Speed;

                                        SaveData.Time_12 = ParamData[11].Time;
                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Speed_12 = ParamData[11].Speed;

                                        SaveData.Time_13 = ParamData[12].Time;
                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Speed_13 = ParamData[12].Speed;

                                        SaveData.Time_14 = ParamData[13].Time;
                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Speed_14 = ParamData[13].Speed;

                                        SaveData.Time_15 = ParamData[14].Time;
                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Speed_15 = ParamData[14].Speed;

                                        SaveData.Time_16 = ParamData[15].Time;
                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Speed_16 = ParamData[15].Speed;

                                        SaveData.Time_17 = ParamData[16].Time;
                                        SaveData.Temperature_17 = ParamData[16].Temperature;
                                        SaveData.Speed_17 = ParamData[16].Speed;

                                        SaveData.Time_18 = ParamData[17].Time;
                                        SaveData.Temperature_18 = ParamData[17].Temperature;
                                        SaveData.Speed_18 = ParamData[17].Speed;

                                        SaveData.Time_19 = ParamData[18].Time;
                                        SaveData.Temperature_19 = ParamData[18].Temperature;
                                        SaveData.Speed_19 = ParamData[18].Speed;

                                        SaveData.Time_20 = ParamData[19].Time;
                                        SaveData.Temperature_20 = ParamData[19].Temperature;
                                        SaveData.Speed_20 = ParamData[19].Speed;

                                        SaveData.Time_21 = ParamData[20].Time;
                                        SaveData.Temperature_21 = ParamData[20].Temperature;
                                        SaveData.Speed_21 = ParamData[20].Speed;

                                        SaveData.Time_22 = ParamData[21].Time;
                                        SaveData.Temperature_22 = ParamData[21].Temperature;
                                        SaveData.Speed_22 = ParamData[21].Speed;

                                        SaveData.Time_23 = ParamData[22].Time;
                                        SaveData.Temperature_23 = ParamData[22].Temperature;
                                        SaveData.Speed_23 = ParamData[22].Speed;

                                        SaveData.Time_24 = ParamData[23].Time;
                                        SaveData.Temperature_24 = ParamData[23].Temperature;
                                        SaveData.Speed_24 = ParamData[23].Speed;

                                        SaveData.Time_25 = ParamData[24].Time;
                                        SaveData.Temperature_25 = ParamData[24].Temperature;
                                        SaveData.Speed_25 = ParamData[24].Speed;

                                        SaveData.Time_26 = ParamData[25].Time;
                                        SaveData.Temperature_26 = ParamData[25].Temperature;
                                        SaveData.Speed_26 = ParamData[25].Speed;

                                        SaveData.Time_27 = ParamData[26].Time;
                                        SaveData.Temperature_27 = ParamData[26].Temperature;
                                        SaveData.Speed_27 = ParamData[26].Speed;

                                        SaveData.Time_28 = ParamData[27].Time;
                                        SaveData.Temperature_28 = ParamData[27].Temperature;
                                        SaveData.Speed_28 = ParamData[27].Speed;

                                        SaveData.Time_29 = ParamData[28].Time;
                                        SaveData.Temperature_29 = ParamData[28].Temperature;
                                        SaveData.Speed_29 = ParamData[28].Speed;

                                        SaveData.Time_30 = ParamData[29].Time;
                                        SaveData.Temperature_30 = ParamData[29].Temperature;
                                        SaveData.Speed_30 = ParamData[29].Speed;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = configModel.Id;
                                    SaveData.ExpName = $"{model.Name}-{CommonConstant.ConvertFlowPathTypeToName(configModel.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigOvenDao.Insert(SaveData);
                                }
                                break;
                        }
                    });
                }

                #endregion

                return new JsonResult(new ResultModel
                {
                    Msg = "新增成功"
                });
            }
            else
            {
                result = BisExperimentTemplateDao.Update(u => new bis_experiment_template()
                {
                    Type = param.ExpTemplateData.Type,
                    Name = param.ExpTemplateData.Name,
                    Number = param.ExpTemplateData.Number,
                    Sort = param.ExpTemplateData.Sort,
                    Remark = param.ExpTemplateData.Remark,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                }, w => w.Id.Equals(param.ExpTemplateData.Id)).Result;

                result = BisExperimentTemplateConfigDao.Update(u => new bis_experiment_template_config()
                {
                    Type = param.ExpTemplateConfigData.Type,
                    ExpectedWorkingHours = param.ExpTemplateConfigData.ExpectedWorkingHours,
                    FlowPathConfig = param.ExpTemplateConfigData.FlowPathConfig,
                    AssemblyConfig = param.ExpTemplateConfigData.AssemblyConfig,
                    Remark = param.ExpTemplateConfigData.Remark,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                }, w => w.Id.Equals(param.ExpTemplateConfigData.Id)).Result;

                if (param.ExpConfigNodeData != null)
                {
                    // 删除原始关联数据
                    result += BisExpConfigNodeDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                    // 按时间进行排序
                    param.ExpConfigNodeData = param.ExpConfigNodeData.OrderBy(o => o.CreateTime).ToList();

                    // 节点排序号
                    int SortValue = 1;

                    param.ExpConfigNodeData.ForEach(item =>
                    {
                        item.Id = Guid.NewGuid().ToString().ToUpper();
                        item.ExpId = param.ExpTemplateConfigData.Id;
                        item.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                        item.Sort = SortValue;
                        item.Remark = "";
                        item.CreateUser = userId;
                        item.CreateUserName = userName;
                        item.CreateTime = now;
                        item.UpdateUser = userId;
                        item.UpdateUserName = userName;
                        item.UpdateTime = now;
                        item.Del_Flag = 0;

                        SortValue++;    // 排序号值加一
                    });
                    result += await BisExpConfigNodeDao.InsertMany(param.ExpConfigNodeData);
                }

                #region 创建关联节点配置数据

                if (param.NodeConfigData != null)
                {
                    param.NodeConfigData.ForEach(async item =>
                    {
                        switch (item.Name)
                        {
                            case DeviceName.Capper:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigCapperDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_capper>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCapperDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Capper2:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigCapperTwoDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_capper_two>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCapperTwoDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.MaterialPositioningTable:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigMaterialPositionTableDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_materialpositiontable>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigMaterialPositionTableDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.UltrasonicCleaningMachine:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigUltrasonicCleaningMachineDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ultrasoniccleaningmachine>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigUltrasonicCleaningMachineDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.PrecisionBalance:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigBalanceDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_balance>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBalanceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.FlourBlending:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigFlourBlendingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_flourblending>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigFlourBlendingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.PipetteDistribution:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigPipetteDistributionDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_pipettedistribution>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigPipetteDistributionDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BallMilling:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigBallMillingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ballmilling>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBallMillingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BallMilling2:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigBallMillingTwoDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_ballmilling_two>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBallMillingTwoDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Crusher:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigCrusherDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_crusher>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCrusherDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.TabletPress:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigTabletPressDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_tabletpress>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigTabletPressDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Scraping:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigScrapingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_scraping>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigScrapingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.CrucibleConversion:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigCrucibleConversionDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_crucibleconversion>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigCrucibleConversionDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Packaging:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigPackagingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_packaging>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigPackagingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.TubeFurnace:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigTubeFurnaceDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_tubefurnace>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<TubeFurnaceModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Time_1 = ParamData[0].Time;

                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Time_2 = ParamData[1].Time;

                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Time_3 = ParamData[2].Time;

                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Time_4 = ParamData[3].Time;

                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Time_5 = ParamData[4].Time;

                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Time_6 = ParamData[5].Time;

                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Time_7 = ParamData[6].Time;

                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Time_8 = ParamData[7].Time;

                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Time_9 = ParamData[8].Time;

                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Time_10 = ParamData[9].Time;

                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Time_11 = ParamData[10].Time;

                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Time_12 = ParamData[11].Time;

                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Time_13 = ParamData[12].Time;

                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Time_14 = ParamData[13].Time;

                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Time_15 = ParamData[14].Time;

                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Time_16 = ParamData[15].Time;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigTubeFurnaceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.BottomFurnace:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigBottomFurnaceDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_bottomfurnace>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<TubeFurnaceModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Time_1 = ParamData[0].Time;

                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Time_2 = ParamData[1].Time;

                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Time_3 = ParamData[2].Time;

                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Time_4 = ParamData[3].Time;

                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Time_5 = ParamData[4].Time;

                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Time_6 = ParamData[5].Time;

                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Time_7 = ParamData[6].Time;

                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Time_8 = ParamData[7].Time;

                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Time_9 = ParamData[8].Time;

                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Time_10 = ParamData[9].Time;

                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Time_11 = ParamData[10].Time;

                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Time_12 = ParamData[11].Time;

                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Time_13 = ParamData[12].Time;

                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Time_14 = ParamData[13].Time;

                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Time_15 = ParamData[14].Time;

                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Time_16 = ParamData[15].Time;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigBottomFurnaceDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.SolidLiquidTesting:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigSolidLiquidTestingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_solidliquidtesting>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigSolidLiquidTestingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.ElectroChemistryTesting:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigElectroChemistryTestingDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    bis_expconfig_electrochemistrytesting ConfigData = new bis_expconfig_electrochemistrytesting();
                                    switch (SaveData.SelExpId)
                                    {
                                        // 实验配置-0 开路电位(电分析)
                                        case "0":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_kldw"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                            }
                                            break;
                                        // 实验配置-1 线性扫描伏安法(LSV)
                                        case "1":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xxsmfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-2 循环伏安法
                                        case "2":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xhfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-3 循环伏安法(多循环)
                                        case "3":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_xhfafdxh"].ToString());
                                                SaveData.IsUseInitialPotential = ConfigData.IsUseInitialPotential;
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.TopPotential2 = ConfigData.TopPotential2;
                                                SaveData.TopPotential2VSType = ConfigData.TopPotential2VSType;
                                                SaveData.IsUseFinallyPotential = ConfigData.IsUseFinallyPotential;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.ScanRate = ConfigData.ScanRate;
                                                SaveData.CycleCount = ConfigData.CycleCount;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-4 恒电位
                                        case "4":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_hdw"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-5 恒电流
                                        case "5":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_hdl"].ToString());
                                                SaveData.TimePerPoint = ConfigData.TimePerPoint;
                                                SaveData.ContinueTime = ConfigData.ContinueTime;
                                                SaveData.Current = ConfigData.Current;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-6 交流阻抗(电压)
                                        case "6":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jlzkdy"].ToString());
                                                SaveData.IsVolEIS = ConfigData.IsVolEIS;
                                                SaveData.StartFreq = ConfigData.StartFreq;
                                                SaveData.EndFreq = ConfigData.EndFreq;
                                                SaveData.Amplitude = ConfigData.Amplitude;
                                                SaveData.IntervalType = ConfigData.IntervalType;
                                                SaveData.PointCount = ConfigData.PointCount;
                                                SaveData.Voltage = ConfigData.Voltage;
                                                SaveData.VoltageVSType = ConfigData.VoltageVSType;
                                            }
                                            break;
                                        // 实验配置-7 交流阻抗(电流)
                                        case "7":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jlzkdl"].ToString());
                                                SaveData.IsVolEIS = ConfigData.IsVolEIS;
                                                SaveData.StartFreq = ConfigData.StartFreq;
                                                SaveData.EndFreq = ConfigData.EndFreq;
                                                SaveData.Amplitude = ConfigData.Amplitude;
                                                SaveData.IntervalType = ConfigData.IntervalType;
                                                SaveData.PointCount = ConfigData.PointCount;
                                                SaveData.Voltage = ConfigData.Voltage;
                                            }
                                            break;
                                        // 实验配置-8 阶梯循环伏安法
                                        case "8":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxhfaf"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-9 阶梯循环伏安法(多循环)
                                        case "9":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxhfafdxh"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.TopPotential1 = ConfigData.TopPotential1;
                                                SaveData.TopPotential1VSType = ConfigData.TopPotential1VSType;
                                                SaveData.TopPotential2 = ConfigData.TopPotential2;
                                                SaveData.TopPotential2VSType = ConfigData.TopPotential2VSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-10 阶梯线性扫描伏安法(SLSV)
                                        case "10":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_jtxxsmfafslsv"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                        // 实验配置-11 Tafel
                                        case "11":
                                            {
                                                ConfigData = JavaScriptSerializer.Deserialize<bis_expconfig_electrochemistrytesting>(jo["expconfig_tafel"].ToString());
                                                SaveData.InitialPotential = ConfigData.InitialPotential;
                                                SaveData.InitialPotentialVSType = ConfigData.InitialPotentialVSType;
                                                SaveData.FinallyPotential = ConfigData.FinallyPotential;
                                                SaveData.FinallyPotentialVSType = ConfigData.FinallyPotentialVSType;
                                                SaveData.StepHeight = ConfigData.StepHeight;
                                                SaveData.StepTime = ConfigData.StepTime;
                                                SaveData.IsVoltageRandAuto = ConfigData.IsVoltageRandAuto;
                                                SaveData.VoltageRand = ConfigData.VoltageRand;
                                                SaveData.IsCurrentRandAuto = ConfigData.IsCurrentRandAuto;
                                                SaveData.CurrentRand = ConfigData.CurrentRand;
                                            }
                                            break;
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigElectroChemistryTestingDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.XRDDevice:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigXRDTestDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_xrdtest>(item.Data.ToString());
                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigXRDTestDao.Insert(SaveData);
                                }
                                break;
                            case DeviceName.Oven:
                                {
                                    // 删除原始关联数据
                                    result += BisExpConfigOvenDao.Delete(w => w.ExpId.Equals(param.ExpTemplateConfigData.Id)).Result;

                                    var SaveData = JavaScriptSerializer.Deserialize<bis_expconfig_oven>(item.Data.ToString());

                                    JObject jo = JObject.Parse(item.Data.ToString());
                                    var ParamData = JavaScriptSerializer.Deserialize<List<OvenModel>>(jo["param"].ToString());
                                    try
                                    {
                                        SaveData.Time_1 = ParamData[0].Time;
                                        SaveData.Temperature_1 = ParamData[0].Temperature;
                                        SaveData.Speed_1 = ParamData[0].Speed;

                                        SaveData.Time_2 = ParamData[1].Time;
                                        SaveData.Temperature_2 = ParamData[1].Temperature;
                                        SaveData.Speed_2 = ParamData[1].Speed;

                                        SaveData.Time_3 = ParamData[2].Time;
                                        SaveData.Temperature_3 = ParamData[2].Temperature;
                                        SaveData.Speed_3 = ParamData[2].Speed;

                                        SaveData.Time_4 = ParamData[3].Time;
                                        SaveData.Temperature_4 = ParamData[3].Temperature;
                                        SaveData.Speed_4 = ParamData[3].Speed;

                                        SaveData.Time_5 = ParamData[4].Time;
                                        SaveData.Temperature_5 = ParamData[4].Temperature;
                                        SaveData.Speed_5 = ParamData[4].Speed;

                                        SaveData.Time_6 = ParamData[5].Time;
                                        SaveData.Temperature_6 = ParamData[5].Temperature;
                                        SaveData.Speed_6 = ParamData[5].Speed;

                                        SaveData.Time_7 = ParamData[6].Time;
                                        SaveData.Temperature_7 = ParamData[6].Temperature;
                                        SaveData.Speed_7 = ParamData[6].Speed;

                                        SaveData.Time_8 = ParamData[7].Time;
                                        SaveData.Temperature_8 = ParamData[7].Temperature;
                                        SaveData.Speed_8 = ParamData[7].Speed;

                                        SaveData.Time_9 = ParamData[8].Time;
                                        SaveData.Temperature_9 = ParamData[8].Temperature;
                                        SaveData.Speed_9 = ParamData[8].Speed;

                                        SaveData.Time_10 = ParamData[9].Time;
                                        SaveData.Temperature_10 = ParamData[9].Temperature;
                                        SaveData.Speed_10 = ParamData[9].Speed;

                                        SaveData.Time_11 = ParamData[10].Time;
                                        SaveData.Temperature_11 = ParamData[10].Temperature;
                                        SaveData.Speed_11 = ParamData[10].Speed;

                                        SaveData.Time_12 = ParamData[11].Time;
                                        SaveData.Temperature_12 = ParamData[11].Temperature;
                                        SaveData.Speed_12 = ParamData[11].Speed;

                                        SaveData.Time_13 = ParamData[12].Time;
                                        SaveData.Temperature_13 = ParamData[12].Temperature;
                                        SaveData.Speed_13 = ParamData[12].Speed;

                                        SaveData.Time_14 = ParamData[13].Time;
                                        SaveData.Temperature_14 = ParamData[13].Temperature;
                                        SaveData.Speed_14 = ParamData[13].Speed;

                                        SaveData.Time_15 = ParamData[14].Time;
                                        SaveData.Temperature_15 = ParamData[14].Temperature;
                                        SaveData.Speed_15 = ParamData[14].Speed;

                                        SaveData.Time_16 = ParamData[15].Time;
                                        SaveData.Temperature_16 = ParamData[15].Temperature;
                                        SaveData.Speed_16 = ParamData[15].Speed;

                                        SaveData.Time_17 = ParamData[16].Time;
                                        SaveData.Temperature_17 = ParamData[16].Temperature;
                                        SaveData.Speed_17 = ParamData[16].Speed;

                                        SaveData.Time_18 = ParamData[17].Time;
                                        SaveData.Temperature_18 = ParamData[17].Temperature;
                                        SaveData.Speed_18 = ParamData[17].Speed;

                                        SaveData.Time_19 = ParamData[18].Time;
                                        SaveData.Temperature_19 = ParamData[18].Temperature;
                                        SaveData.Speed_19 = ParamData[18].Speed;

                                        SaveData.Time_20 = ParamData[19].Time;
                                        SaveData.Temperature_20 = ParamData[19].Temperature;
                                        SaveData.Speed_20 = ParamData[19].Speed;

                                        SaveData.Time_21 = ParamData[20].Time;
                                        SaveData.Temperature_21 = ParamData[20].Temperature;
                                        SaveData.Speed_21 = ParamData[20].Speed;

                                        SaveData.Time_22 = ParamData[21].Time;
                                        SaveData.Temperature_22 = ParamData[21].Temperature;
                                        SaveData.Speed_22 = ParamData[21].Speed;

                                        SaveData.Time_23 = ParamData[22].Time;
                                        SaveData.Temperature_23 = ParamData[22].Temperature;
                                        SaveData.Speed_23 = ParamData[22].Speed;

                                        SaveData.Time_24 = ParamData[23].Time;
                                        SaveData.Temperature_24 = ParamData[23].Temperature;
                                        SaveData.Speed_24 = ParamData[23].Speed;

                                        SaveData.Time_25 = ParamData[24].Time;
                                        SaveData.Temperature_25 = ParamData[24].Temperature;
                                        SaveData.Speed_25 = ParamData[24].Speed;

                                        SaveData.Time_26 = ParamData[25].Time;
                                        SaveData.Temperature_26 = ParamData[25].Temperature;
                                        SaveData.Speed_26 = ParamData[25].Speed;

                                        SaveData.Time_27 = ParamData[26].Time;
                                        SaveData.Temperature_27 = ParamData[26].Temperature;
                                        SaveData.Speed_27 = ParamData[26].Speed;

                                        SaveData.Time_28 = ParamData[27].Time;
                                        SaveData.Temperature_28 = ParamData[27].Temperature;
                                        SaveData.Speed_28 = ParamData[27].Speed;

                                        SaveData.Time_29 = ParamData[28].Time;
                                        SaveData.Temperature_29 = ParamData[28].Temperature;
                                        SaveData.Speed_29 = ParamData[28].Speed;

                                        SaveData.Time_30 = ParamData[29].Time;
                                        SaveData.Temperature_30 = ParamData[29].Temperature;
                                        SaveData.Speed_30 = ParamData[29].Speed;
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"已超出索引, 取消读取 {ex.Message}");
                                    }

                                    SaveData.Id = Guid.NewGuid().ToString().ToUpper();
                                    SaveData.ExpId = param.ExpTemplateConfigData.Id;
                                    SaveData.ExpName = $"{param.ExpTemplateData.Name}-{CommonConstant.ConvertFlowPathTypeToName(param.ExpTemplateConfigData.Type)}";
                                    SaveData.NodeId = item.Id;
                                    SaveData.Sort = 1;
                                    SaveData.Remark = "";
                                    SaveData.CreateUser = userId;
                                    SaveData.CreateUserName = userName;
                                    SaveData.CreateTime = now;
                                    SaveData.UpdateUser = userId;
                                    SaveData.UpdateUserName = userName;
                                    SaveData.UpdateTime = now;
                                    SaveData.Del_Flag = 0;

                                    //Console.WriteLine();
                                    result += await BisExpConfigOvenDao.Insert(SaveData);
                                }
                                break;
                        }
                    });
                }

                #endregion

                return new JsonResult(new ResultModel
                {
                    Msg = "编辑成功"
                });
            }

            #endregion 数据提交
        }

        #endregion

        #region 批量删除实验模板信息

        /// <summary>
        /// 批量删除实验模板信息
        /// </summary>
        /// <param name="param">更新参数集</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> DelExperimentTemplate(UpdateModel param)
        {
            Console.WriteLine("\n批量删除实验模板信息：DelExperimentTemplate");

            #region 参数效验

            Console.WriteLine($"Id：{param.Id}");

            if (string.IsNullOrEmpty(param.Id))
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion

            #region 获取登录用户相关信息

            string userId = string.Empty;
            string userName = string.Empty;
            try
            {
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userName = Accessor.HttpContext.User.Claims.First(i => i.Type == "userName").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            string[] idArray = param.Id.Split(',');

            int result = 0;
            foreach (var item in idArray)
            {
                Console.WriteLine(item);
                if (!item.Equals(userId))
                {
                    result += await BisExperimentTemplateDao.Update(u => new bis_experiment_template
                    {
                        Del_Flag = 1
                    }, w => w.Id.Equals(item));
                }
            }

            return new JsonResult(new ResultModel
            {
                Msg = "删除成功",
                Data = result
            });
        }

        #endregion

        #region 更新实验模板顺序

        /// <summary>
        /// 更新实验模板顺序
        /// </summary>
        /// <param name="param">更新参数集</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> UpdateExperimentTemplateSort(UpdateModel param)
        {
            await Task.Run(() => { Console.WriteLine("\n更新实验模板顺序：UpdateExperimentTemplateSort"); });

            #region 参数效验

            Console.WriteLine($"SetValueData：{param.SetValueData}");

            if (param.SetValueData == null)
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion

            #region 获取登录用户相关信息

            string userId = string.Empty;
            string userName = string.Empty;
            try
            {
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userName = Accessor.HttpContext.User.Claims.First(i => i.Type == "userName").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            DateTime now = DateTime.Now;

            int result = 0;
            Parallel.ForEach(param.SetValueData, async item =>
            {
                result += await BisExperimentTemplateDao.Update(u => new bis_experiment_template
                {
                    Sort = int.Parse(item.Value)
                }, w => w.Id.Equals(item.Id));
            });

            return new JsonResult(new ResultModel
            {
                Msg = "提交成功",
                Data = result
            });
        }

        #endregion

        #region 获取实验模板关联配置列表

        /// <summary>
        /// 获取实验模板关联配置列表
        /// </summary>
        /// <param name="param">搜索条件</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> ExperimentTemplateConfigList(SearchModel param)
        {
            Console.WriteLine("\n获取实验模板关联配置列表：ExperimentTemplateConfigList");

            #region 获取登录用户相关信息

            string orgId = string.Empty;
            string userId = string.Empty;
            string userRoleId = string.Empty;
            try
            {
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userRoleId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userRoleId").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            // 初始化数据查询表达式
            Expression<Func<bis_experiment_template_config, bool>> expression = w => w.Del_Flag == 0;

            Console.WriteLine($"ExpTemplateId：{param.ExpTemplateId}");
            if (!string.IsNullOrEmpty(param.ExpTemplateId))
            {
                expression = expression.And(w => w.ExpTemplateId.Equals(param.ExpTemplateId));
            }

            Console.WriteLine($"Type：{param.Type}");
            if (!string.IsNullOrEmpty(param.Type))
            {
                string[] conditions = param.Type.Split(',');
                Expression<Func<bis_experiment_template_config, bool>> expressionSub = w => w.Type.Equals(conditions.GetValue(0).ToString());
                expressionSub = expressionSub.And(w => w.Del_Flag == 0);
                for (int i = 1; i < conditions.Length; i++)
                {
                    var statusTmp = conditions.GetValue(i).ToString();
                    expressionSub = expressionSub.Or(w => w.Type.Equals(statusTmp));
                }
                expression = expression.And(expressionSub);
            }

            dynamic result = null;
            if (param.Page != null && param.Limit != null)
            {
                result = await BisExperimentTemplateConfigDao.QueryByWherePage(param.Page.Value, param.Limit.Value, expression, o => o.CreateTime, OrderByType.Desc);
            }
            else
            {
                result = await BisExperimentTemplateConfigDao.QueryByWhere(expression, o => o.CreateTime, OrderByType.Desc);
            }
            var count = await BisExperimentTemplateConfigDao.QueryCount(expression);

            return new JsonResult(new ResultModel
            {
                Count = count,
                Data = result
            });
        }

        #endregion

        #region 获取实验模板关联配置详情

        /// <summary>
        /// 获取实验模板关联配置详情
        /// </summary>
        /// <param name="param">搜索条件</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> ExperimentTemplateConfigDetail(SearchModel param)
        {
            Console.WriteLine("\n获取实验模板关联配置详情：ExperimentTemplateConfigDetail");

            #region 参数校验

            Console.WriteLine($"Id：{param.Id}");
            if (string.IsNullOrEmpty(param.Id))
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion

            var result = await BisExperimentTemplateConfigDao.QuerySingle(w => w.Del_Flag == 0 && w.Id.Equals(param.Id));

            // 获取配置数据
            List<NodeConfigModel> NodeConfigData = JavaScriptSerializer.Deserialize<List<NodeConfigModel>>(result.AssemblyConfig);

            return new JsonResult(new ResultModel
            {
                Data = result,
                Data2 = NodeConfigData
            });
        }

        #endregion

        #region 提交实验模板关联配置信息

        /// <summary>
        /// 提交实验模板关联配置信息
        /// </summary>
        /// <param name="param">更新参数集</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> SubmitExperimentTemplateConfig(UpdateModel param)
        {
            Console.WriteLine("\n提交实验模板信息：SubmitExperimentTemplateConfig");

            #region 参数、数据校验

            Console.WriteLine($"ExpTemplateConfigData：{param.ExpTemplateConfigData}");

            if (param.ExpTemplateConfigData == null)
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion 

            #region 获取所需数据

            #region 获取登录用户相关信息

            string userId = string.Empty;
            string userName = string.Empty;
            string orgId = string.Empty;
            string orgName = string.Empty;
            try
            {
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userName = Accessor.HttpContext.User.Claims.First(i => i.Type == "userName").Value;
                orgId = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgId").Value;
                orgName = Accessor.HttpContext.User.Claims.First(i => i.Type == "orgName").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            #endregion

            #region 数据提交

            DateTime now = DateTime.Now;
            Guid guid = Guid.NewGuid();
            string newId = guid.ToString().ToUpper();

            int result = 0;

            // 如果Guid为空时则新增，否则为编辑
            if (string.IsNullOrEmpty(param.ExpTemplateConfigData.Id))
            {
                var model = new bis_experiment_template_config()
                {
                    Id = newId,
                    ExpTemplateId = param.ExpTemplateConfigData.ExpTemplateId,
                    Type = param.ExpTemplateConfigData.Type,
                    ExpectedWorkingHours = param.ExpTemplateConfigData.ExpectedWorkingHours,
                    FlowPathConfig = param.ExpTemplateConfigData.FlowPathConfig,
                    AssemblyConfig = param.ExpTemplateConfigData.AssemblyConfig,
                    Remark = param.ExpTemplateConfigData.Remark,
                    OrgGuid = orgId,
                    OrgName = orgName,
                    CreateUser = userId,
                    CreateUserName = userName,
                    CreateTime = now,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                    Del_Flag = 0
                };
                result = await BisExperimentTemplateConfigDao.Insert(model);

                return new JsonResult(new ResultModel
                {
                    Msg = "新增成功"
                });
            }
            else
            {
                result = BisExperimentTemplateConfigDao.Update(u => new bis_experiment_template_config()
                {
                    ExpTemplateId = param.ExpTemplateConfigData.ExpTemplateId,
                    Type = param.ExpTemplateConfigData.Type,
                    ExpectedWorkingHours = param.ExpTemplateConfigData.ExpectedWorkingHours,
                    FlowPathConfig = param.ExpTemplateConfigData.FlowPathConfig,
                    AssemblyConfig = param.ExpTemplateConfigData.AssemblyConfig,
                    Remark = param.ExpTemplateConfigData.Remark,
                    UpdateUser = userId,
                    UpdateUserName = userName,
                    UpdateTime = now,
                }, w => w.Id.Equals(param.ExpTemplateConfigData.Id)).Result;

                return new JsonResult(new ResultModel
                {
                    Msg = "编辑成功"
                });
            }

            #endregion 数据提交
        }

        #endregion

        #region 批量删除实验模板关联配置信息

        /// <summary>
        /// 批量删除实验模板关联配置信息
        /// </summary>
        /// <param name="param">更新参数集</param>
        /// <returns>JSON结果集</returns>
        public async Task<JsonResult> DelExperimentTemplateConfig(UpdateModel param)
        {
            Console.WriteLine("\n批量删除实验模板关联配置信息：DelExperimentTemplateConfig");

            #region 参数效验

            Console.WriteLine($"Id：{param.Id}");

            if (string.IsNullOrEmpty(param.Id))
            {
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "必填参数不能为空"
                });
            }

            #endregion

            #region 获取登录用户相关信息

            string userId = string.Empty;
            string userName = string.Empty;
            try
            {
                userId = Accessor.HttpContext.User.Claims.First(i => i.Type == "userId").Value;
                userName = Accessor.HttpContext.User.Claims.First(i => i.Type == "userName").Value;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return new JsonResult(new ResultModel
                {
                    Success = false,
                    Msg = "Token已过期, 请重新登录"
                });
            }

            #endregion

            string[] idArray = param.Id.Split(',');

            int result = 0;
            foreach (var item in idArray)
            {
                Console.WriteLine(item);
                if (!item.Equals(userId))
                {
                    result += await BisExperimentTemplateConfigDao.Update(u => new bis_experiment_template_config
                    {
                        Del_Flag = 1
                    }, w => w.Id.Equals(item));
                }
            }

            return new JsonResult(new ResultModel
            {
                Msg = "删除成功",
                Data = result
            });
        }

        #endregion

    }
}